From d34416ea02c5e437cdeb75167a7ffc11eb5506db Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 4 Aug 2015 11:04:54 -0600 Subject: [PATCH 001/381] define-inline: fix call with multiple keyword arguments --- pkgs/racket-test-core/tests/racket/optimize.rktl | 8 ++++++++ racket/collects/racket/performance-hint.rkt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 693c93ed52..90096b6dee 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -4430,6 +4430,14 @@ (define-inline (odd? x) (if (zero? x) #f (even? (sub1 x)))) (test/output (odd? 2) #f "") + + ;; multiple keyword arguments that have to be sorted: + (define-inline (sub #:a a #:b b) + (- a b)) + (test/output (sub #:a 2 #:b 1) + 1 "") + (test/output (sub #:b 1 #:a 2) + 1 "") ) diff --git a/racket/collects/racket/performance-hint.rkt b/racket/collects/racket/performance-hint.rkt index 94a9f32f23..84fada48d3 100644 --- a/racket/collects/racket/performance-hint.rkt +++ b/racket/collects/racket/performance-hint.rkt @@ -112,7 +112,7 @@ stringstring - (syntax-e kw))))]) + (syntax-e (car kw)))))]) (keyword-apply function-aux (map (lambda (x) (syntax-e (car x))) From c308915047c7781da5da410d05ba9bd2235c7a67 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 4 Aug 2015 21:20:20 -0600 Subject: [PATCH 002/381] minor streamlining of foreign-call path JIT-inline `cpointer-tag` and `set-cpointer-tag!`, plus minor shortcuts and GC hints in Racket->C conversion. --- racket/collects/compiler/private/xform.rkt | 1 + racket/src/foreign/foreign.c | 110 ++++++++++++--------- racket/src/foreign/foreign.rktc | 58 +++++++---- racket/src/foreign/rktc-utils.rkt | 10 +- racket/src/racket/src/jit.h | 1 + racket/src/racket/src/jit_ts.c | 4 + racket/src/racket/src/jitcommon.c | 24 +++++ racket/src/racket/src/jitinline.c | 62 ++++++++++++ racket/src/racket/src/schpriv.h | 3 + 9 files changed, 207 insertions(+), 66 deletions(-) diff --git a/racket/collects/compiler/private/xform.rkt b/racket/collects/compiler/private/xform.rkt index 2e62629570..63e8dd4c2a 100644 --- a/racket/collects/compiler/private/xform.rkt +++ b/racket/collects/compiler/private/xform.rkt @@ -956,6 +956,7 @@ '(exit scheme_wrong_type scheme_wrong_number scheme_wrong_syntax scheme_wrong_count scheme_wrong_count_m scheme_wrong_rator scheme_read_err + scheme_wrong_contract scheme_contract_error scheme_raise_exn scheme_signal_error scheme_raise_out_of_memory )) diff --git a/racket/src/foreign/foreign.c b/racket/src/foreign/foreign.c index 1a4772686b..1bf1c897dd 100644 --- a/racket/src/foreign/foreign.c +++ b/racket/src/foreign/foreign.c @@ -1075,7 +1075,7 @@ XFORM_NONGCING static int is_gcable_pointer(Scheme_Object *o) { * type by the basetype field.) */ /* ctype structure definition */ -static Scheme_Type ctype_tag; +#define ctype_tag scheme_ctype_type typedef struct ctype_struct { Scheme_Object so; Scheme_Object* basetype; @@ -1705,6 +1705,13 @@ static Scheme_Object *foreign_cpointer_tag(int argc, Scheme_Object *argv[]) } #undef MYNAME +Scheme_Object *scheme_cpointer_tag(Scheme_Object *ptr) +{ + Scheme_Object *a[1]; + a[0] = ptr; + return foreign_cpointer_tag(1, a); +} + #define MYNAME "set-cpointer-tag!" static Scheme_Object *foreign_set_cpointer_tag_bang(int argc, Scheme_Object *argv[]) { @@ -1717,6 +1724,14 @@ static Scheme_Object *foreign_set_cpointer_tag_bang(int argc, Scheme_Object *arg } #undef MYNAME +void scheme_set_cpointer_tag(Scheme_Object *ptr, Scheme_Object *val) +{ + Scheme_Object *a[2]; + a[0] = ptr; + a[1] = val; + (void)foreign_set_cpointer_tag_bang(2, a); +} + #define MYNAME "cpointer-gcable?" static Scheme_Object *foreign_cpointer_gcable_p(int argc, Scheme_Object *argv[]) { @@ -1817,13 +1832,14 @@ static Scheme_Object *C2SCHEME(Scheme_Object *already_ptr, Scheme_Object *type, } #undef REF_CTYPE -static void wrong_value(const char *who, const char *type, Scheme_Object *val) +static void *wrong_value(const char *who, const char *type, Scheme_Object *val) { scheme_contract_error(who, "given value does not fit primitive C type", "C type", 0, type, "given value", 1, val, NULL); + return NULL; } /* On big endian machines we need to know whether we're pulling a value from an @@ -1839,14 +1855,20 @@ static void wrong_value(const char *who, const char *type, Scheme_Object *val) * then a struct or array value will be *copied* into dst. */ static void* SCHEME2C(const char *who, Scheme_Object *type, void *dst, intptr_t delta, - Scheme_Object *val, intptr_t *basetype_p, intptr_t *_offset, + Scheme_Object *val, GC_CAN_IGNORE intptr_t *basetype_p, GC_CAN_IGNORE intptr_t *_offset, int ret_loc) { - if (!SCHEME_CTYPEP(type)) - scheme_wrong_contract(who, "ctype?", 0, 1, &type); + /* redundant check: + if (!SCHEME_CTYPEP(type)) + scheme_wrong_contract(who, "ctype?", 0, 1, &type); */ while (CTYPE_USERP(type)) { - if (!SCHEME_FALSEP(CTYPE_USER_S2C(type))) - val = _scheme_apply(CTYPE_USER_S2C(type), 1, (Scheme_Object**)(&val)); + GC_CAN_IGNORE Scheme_Object *f = CTYPE_USER_S2C(type); + if (!SCHEME_FALSEP(f)) { + if (SAME_TYPE(SCHEME_TYPE(f), scheme_native_closure_type)) + val = _scheme_apply_native(f, 1, (Scheme_Object**)(&val)); + else + val = _scheme_apply(f, 1, (Scheme_Object**)(&val)); + } type = CTYPE_BASETYPE(type); } if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) { @@ -1861,10 +1883,10 @@ static void* SCHEME2C(const char *who, else if (SCHEME_FALSEP(val)) ((void**)W_OFFSET(dst,delta))[0] = NULL; else /* ((void**)W_OFFSET(dst,delta))[0] = val; */ - wrong_value(who, "_fpointer", val); + return wrong_value(who, "_fpointer", val); } else switch (CTYPE_PRIMLABEL(type)) { case FOREIGN_void: - if (!ret_loc) wrong_value(who, "_void", val);; + if (!ret_loc) return wrong_value(who, "_void", val);; break; case FOREIGN_int8: # ifdef SCHEME_BIG_ENDIAN @@ -1878,7 +1900,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(get_byte_val(val,&(((Tsint8*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_int8", val);; + if (!(get_byte_val(val,&(((Tsint8*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_int8", val);; return NULL; case FOREIGN_uint8: # ifdef SCHEME_BIG_ENDIAN @@ -1892,7 +1914,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(get_ubyte_val(val,&(((Tuint8*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_uint8", val);; + if (!(get_ubyte_val(val,&(((Tuint8*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_uint8", val);; return NULL; case FOREIGN_int16: # ifdef SCHEME_BIG_ENDIAN @@ -1906,7 +1928,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(get_short_val(val,&(((Tsint16*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_int16", val);; + if (!(get_short_val(val,&(((Tsint16*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_int16", val);; return NULL; case FOREIGN_uint16: # ifdef SCHEME_BIG_ENDIAN @@ -1920,7 +1942,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(get_ushort_val(val,&(((Tuint16*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_uint16", val);; + if (!(get_ushort_val(val,&(((Tuint16*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_uint16", val);; return NULL; case FOREIGN_int32: # ifdef SCHEME_BIG_ENDIAN @@ -1934,7 +1956,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(scheme_get_realint_val(val,&(((Tsint32*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_int32", val);; + if (!(scheme_get_realint_val(val,&(((Tsint32*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_int32", val);; return NULL; case FOREIGN_uint32: # ifdef SCHEME_BIG_ENDIAN @@ -1948,7 +1970,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(scheme_get_unsigned_realint_val(val,&(((Tuint32*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_uint32", val);; + if (!(scheme_get_unsigned_realint_val(val,&(((Tuint32*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_uint32", val);; return NULL; case FOREIGN_int64: # ifdef SCHEME_BIG_ENDIAN @@ -1962,7 +1984,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(scheme_get_long_long_val(val,&(((Tsint64*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_int64", val);; + if (!(scheme_get_long_long_val(val,&(((Tsint64*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_int64", val);; return NULL; case FOREIGN_uint64: # ifdef SCHEME_BIG_ENDIAN @@ -1976,7 +1998,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(scheme_get_unsigned_long_long_val(val,&(((Tuint64*)W_OFFSET(dst,delta))[0])))) wrong_value(who, "_uint64", val);; + if (!(scheme_get_unsigned_long_long_val(val,&(((Tuint64*)W_OFFSET(dst,delta))[0])))) return wrong_value(who, "_uint64", val);; return NULL; case FOREIGN_fixint: # ifdef SCHEME_BIG_ENDIAN @@ -1996,7 +2018,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(Tsint32, SCHEME_INT_VAL(val)); (((Tsint32*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_fixint", val);; + return wrong_value(who, "_fixint", val);; return NULL; /* hush the compiler */ } case FOREIGN_ufixint: @@ -2017,7 +2039,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(Tuint32, SCHEME_UINT_VAL(val)); (((Tuint32*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_ufixint", val);; + return wrong_value(who, "_ufixint", val);; return NULL; /* hush the compiler */ } case FOREIGN_fixnum: @@ -2038,7 +2060,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(intptr_t, SCHEME_INT_VAL(val)); (((intptr_t*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_fixnum", val);; + return wrong_value(who, "_fixnum", val);; return NULL; /* hush the compiler */ } case FOREIGN_ufixnum: @@ -2059,7 +2081,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(uintptr_t, SCHEME_UINT_VAL(val)); (((uintptr_t*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_ufixnum", val);; + return wrong_value(who, "_ufixnum", val);; return NULL; /* hush the compiler */ } case FOREIGN_float: @@ -2080,7 +2102,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(float, SCHEME_FLOAT_VAL(val)); (((float*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_float", val);; + return wrong_value(who, "_float", val);; return NULL; /* hush the compiler */ } case FOREIGN_double: @@ -2101,7 +2123,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(double, SCHEME_FLOAT_VAL(val)); (((double*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_double", val);; + return wrong_value(who, "_double", val);; return NULL; /* hush the compiler */ } case FOREIGN_longdouble: @@ -2122,7 +2144,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_NO_TYPE_CAST(mz_long_double, SCHEME_MAYBE_LONG_DBL_VAL(val)); (((mz_long_double*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_longdouble", val);; + return wrong_value(who, "_longdouble", val);; return NULL; /* hush the compiler */ } case FOREIGN_doubleS: @@ -2143,7 +2165,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(double, scheme_real_to_double(val)); (((double*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_double*", val);; + return wrong_value(who, "_double*", val);; return NULL; /* hush the compiler */ } case FOREIGN_bool: @@ -2164,7 +2186,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(int, SCHEME_TRUEP(val)); (((int*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_bool", val);; + return wrong_value(who, "_bool", val);; return NULL; /* hush the compiler */ } case FOREIGN_stdbool: @@ -2185,7 +2207,7 @@ static void* SCHEME2C(const char *who, tmp = MZ_TYPE_CAST(stdbool, SCHEME_TRUEP(val)); (((stdbool*)W_OFFSET(dst,delta))[0]) = tmp; return NULL; } else { - wrong_value(who, "_stdbool", val);; + return wrong_value(who, "_stdbool", val);; return NULL; /* hush the compiler */ } case FOREIGN_string_ucs_4: @@ -2212,7 +2234,7 @@ static void* SCHEME2C(const char *who, return tmp; } } else { - wrong_value(who, "_string/ucs-4", val);; + return wrong_value(who, "_string/ucs-4", val);; return NULL; /* hush the compiler */ } case FOREIGN_string_utf_16: @@ -2239,7 +2261,7 @@ static void* SCHEME2C(const char *who, return tmp; } } else { - wrong_value(who, "_string/utf-16", val);; + return wrong_value(who, "_string/utf-16", val);; return NULL; /* hush the compiler */ } case FOREIGN_bytes: @@ -2266,7 +2288,7 @@ static void* SCHEME2C(const char *who, return tmp; } } else { - wrong_value(who, "_bytes", val);; + return wrong_value(who, "_bytes", val);; return NULL; /* hush the compiler */ } case FOREIGN_path: @@ -2293,7 +2315,7 @@ static void* SCHEME2C(const char *who, return tmp; } } else { - wrong_value(who, "_path", val);; + return wrong_value(who, "_path", val);; return NULL; /* hush the compiler */ } case FOREIGN_symbol: @@ -2320,7 +2342,7 @@ static void* SCHEME2C(const char *who, return tmp; } } else { - wrong_value(who, "_symbol", val);; + return wrong_value(who, "_symbol", val);; return NULL; /* hush the compiler */ } case FOREIGN_pointer: @@ -2351,7 +2373,7 @@ static void* SCHEME2C(const char *who, return _offset ? tmp : (void*)W_OFFSET(tmp, toff); } } else { - wrong_value(who, "_pointer", val);; + return wrong_value(who, "_pointer", val);; return NULL; /* hush the compiler */ } case FOREIGN_gcpointer: @@ -2382,7 +2404,7 @@ static void* SCHEME2C(const char *who, return _offset ? tmp : (void*)W_OFFSET(tmp, toff); } } else { - wrong_value(who, "_gcpointer", val);; + return wrong_value(who, "_gcpointer", val);; return NULL; /* hush the compiler */ } case FOREIGN_scheme: @@ -2409,7 +2431,7 @@ static void* SCHEME2C(const char *who, return tmp; } } else { - wrong_value(who, "_scheme", val);; + return wrong_value(who, "_scheme", val);; return NULL; /* hush the compiler */ } case FOREIGN_fpointer: @@ -2424,7 +2446,7 @@ static void* SCHEME2C(const char *who, ((int*)W_OFFSET(dst,delta))[0] = 0; } # endif /* FFI_CALLBACK_NEED_INT_CLEAR */ - if (!(ret_loc)) wrong_value(who, "_fpointer", val);; + if (!(ret_loc)) return wrong_value(who, "_fpointer", val);; break; case FOREIGN_struct: case FOREIGN_array: @@ -2433,14 +2455,14 @@ static void* SCHEME2C(const char *who, if (!SCHEME_FFIANYPTRP(val)) { switch (CTYPE_PRIMLABEL(type)) { case FOREIGN_struct: - wrong_value(who, "(_struct ....)", val); + return wrong_value(who, "(_struct ....)", val); break; case FOREIGN_array: - wrong_value(who, "(_array ....)", val); + return wrong_value(who, "(_array ....)", val); break; default: case FOREIGN_union: - wrong_value(who, "(_union ....)", val); + return wrong_value(who, "(_union ....)", val); break; } } @@ -4322,7 +4344,7 @@ void scheme_init_foreign_globals() { ffi_lib_tag = scheme_make_type(""); ffi_obj_tag = scheme_make_type(""); - ctype_tag = scheme_ctype_type; + ; ffi_callback_tag = scheme_make_type(""); # ifdef MZ_PRECISE_GC GC_register_traversers(ffi_lib_tag, ffi_lib_SIZE, ffi_lib_MARK, ffi_lib_FIXUP, 1, 0); @@ -4448,9 +4470,9 @@ void scheme_init_foreign(Scheme_Env *env) scheme_add_global_constant("cpointer?", scheme_make_immed_prim(foreign_cpointer_p, "cpointer?", 1, 1), menv); scheme_add_global_constant("cpointer-tag", - scheme_make_noncm_prim(foreign_cpointer_tag, "cpointer-tag", 1, 1), menv); + scheme_make_inline_noncm_prim(foreign_cpointer_tag, "cpointer-tag", 1, 1), menv); scheme_add_global_constant("set-cpointer-tag!", - scheme_make_noncm_prim(foreign_set_cpointer_tag_bang, "set-cpointer-tag!", 2, 2), menv); + scheme_make_inline_noncm_prim(foreign_set_cpointer_tag_bang, "set-cpointer-tag!", 2, 2), menv); scheme_add_global_constant("cpointer-gcable?", scheme_make_noncm_prim(foreign_cpointer_gcable_p, "cpointer-gcable?", 1, 1), menv); scheme_add_global_constant("ctype-sizeof", @@ -4819,9 +4841,9 @@ void scheme_init_foreign(Scheme_Env *env) scheme_add_global_constant("cpointer?", scheme_make_immed_prim((Scheme_Prim *)unimplemented, "cpointer?", 1, 1), menv); scheme_add_global_constant("cpointer-tag", - scheme_make_noncm_prim((Scheme_Prim *)unimplemented, "cpointer-tag", 1, 1), menv); + scheme_make_inline_noncm_prim((Scheme_Prim *)unimplemented, "cpointer-tag", 1, 1), menv); scheme_add_global_constant("set-cpointer-tag!", - scheme_make_noncm_prim((Scheme_Prim *)unimplemented, "set-cpointer-tag!", 2, 2), menv); + scheme_make_inline_noncm_prim((Scheme_Prim *)unimplemented, "set-cpointer-tag!", 2, 2), menv); scheme_add_global_constant("cpointer-gcable?", scheme_make_noncm_prim((Scheme_Prim *)unimplemented, "cpointer-gcable?", 1, 1), menv); scheme_add_global_constant("ctype-sizeof", diff --git a/racket/src/foreign/foreign.rktc b/racket/src/foreign/foreign.rktc index 135742e75c..22a871fccc 100755 --- a/racket/src/foreign/foreign.rktc +++ b/racket/src/foreign/foreign.rktc @@ -200,7 +200,7 @@ END_XFORM_SKIP; /*****************************************************************************/ /* Library objects */ -@cdefstruct[ffi-lib +@cdefstruct[ffi-lib [] [handle "NON_GCBALE_PTR(void)"] [name "Scheme_Object*"] [objects "Scheme_Hash_Table*"] @@ -271,7 +271,7 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs); /*****************************************************************************/ /* Pull pointers (mostly functions) out of ffi-lib objects */ -@cdefstruct[ffi-obj +@cdefstruct[ffi-obj [] [obj "NON_GCBALE_PTR(void)"] [name "char*"] [lib "NON_GCBALE_PTR(ffi_lib_struct)"]] @@ -973,7 +973,7 @@ XFORM_NONGCING static int is_gcable_pointer(Scheme_Object *o) { * integer is not really needed, since it is possible to identify the * type by the basetype field.) */ -@cdefstruct[ctype +@cdefstruct[ctype [#:tag "scheme_ctype_type"] [basetype "Scheme_Object*"] [scheme_to_c "Scheme_Object*"] [c_to_scheme "Scheme_Object*"]] @@ -1354,7 +1354,7 @@ static void wrong_intptr(const char *who, int which, int argc, Scheme_Object **a /*****************************************************************************/ /* Callback type */ -@cdefstruct[ffi-callback +@cdefstruct[ffi-callback [] [callback "NON_GCBALE_PTR(void)"] [proc "Scheme_Object*"] [itypes "Scheme_Object*"] @@ -1461,7 +1461,7 @@ int scheme_is_cpointer(Scheme_Object *cp) { : scheme_false); } -@cdefine[cpointer-tag 1]{ +@cdefine[cpointer-tag 1 #:kind inline_noncm]{ Scheme_Object *tag = NULL; Scheme_Object *cp; cp = unwrap_cpointer_property(argv[0]); @@ -1471,7 +1471,14 @@ int scheme_is_cpointer(Scheme_Object *cp) { return (tag == NULL) ? scheme_false : tag; } -@cdefine[set-cpointer-tag! 2]{ +Scheme_Object *scheme_cpointer_tag(Scheme_Object *ptr) +{ + Scheme_Object *a[1]; + a[0] = ptr; + return foreign_cpointer_tag(1, a); +} + +@cdefine[set-cpointer-tag! 2 #:kind inline_noncm]{ Scheme_Object *cp; cp = unwrap_cpointer_property(argv[0]); if (!SCHEME_CPTRP(cp)) @@ -1480,6 +1487,14 @@ int scheme_is_cpointer(Scheme_Object *cp) { return scheme_void; } +void scheme_set_cpointer_tag(Scheme_Object *ptr, Scheme_Object *val) +{ + Scheme_Object *a[2]; + a[0] = ptr; + a[1] = val; + (void)foreign_set_cpointer_tag_bang(2, a); +} + @cdefine[cpointer-gcable? 1]{ Scheme_Object *cp; cp = unwrap_cpointer_property(argv[0]); @@ -1555,13 +1570,14 @@ static Scheme_Object *C2SCHEME(Scheme_Object *already_ptr, Scheme_Object *type, } #undef REF_CTYPE -static void wrong_value(const char *who, const char *type, Scheme_Object *val) +static void *wrong_value(const char *who, const char *type, Scheme_Object *val) { scheme_contract_error(who, "given value does not fit primitive C type", "C type", 0, type, "given value", 1, val, NULL); + return NULL; } /* On big endian machines we need to know whether we're pulling a value from an @@ -1577,14 +1593,20 @@ static void wrong_value(const char *who, const char *type, Scheme_Object *val) * then a struct or array value will be *copied* into dst. */ static void* SCHEME2C(const char *who, Scheme_Object *type, void *dst, intptr_t delta, - Scheme_Object *val, intptr_t *basetype_p, intptr_t *_offset, + Scheme_Object *val, GC_CAN_IGNORE intptr_t *basetype_p, GC_CAN_IGNORE intptr_t *_offset, int ret_loc) { - if (!SCHEME_CTYPEP(type)) - scheme_wrong_contract(who, "ctype?", 0, 1, &type); + /* redundant check: + if (!SCHEME_CTYPEP(type)) + scheme_wrong_contract(who, "ctype?", 0, 1, &type); */ while (CTYPE_USERP(type)) { - if (!SCHEME_FALSEP(CTYPE_USER_S2C(type))) - val = _scheme_apply(CTYPE_USER_S2C(type), 1, (Scheme_Object**)(&val)); + GC_CAN_IGNORE Scheme_Object *f = CTYPE_USER_S2C(type); + if (!SCHEME_FALSEP(f)) { + if (SAME_TYPE(SCHEME_TYPE(f), scheme_native_closure_type)) + val = _scheme_apply_native(f, 1, (Scheme_Object**)(&val)); + else + val = _scheme_apply(f, 1, (Scheme_Object**)(&val)); + } type = CTYPE_BASETYPE(type); } if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) { @@ -1599,11 +1621,11 @@ static void* SCHEME2C(const char *who, else if (SCHEME_FALSEP(val)) ((void**)W_OFFSET(dst,delta))[0] = NULL; else /* ((void**)W_OFFSET(dst,delta))[0] = val; */ - wrong_value(who, "_fpointer", val); + return wrong_value(who, "_fpointer", val); } else switch (CTYPE_PRIMLABEL(type)) { @(map-types #:semicolons? #f (define (wrong-type obj type) - @list{wrong_value(who, "_@type", val);}) + @list{return wrong_value(who, "_@type", val);}) @list{ case FOREIGN_@|cname|: @(let* ([x (and ctype @list{(((@|ctype|*)W_OFFSET(dst,delta))[0])})] @@ -1684,14 +1706,14 @@ static void* SCHEME2C(const char *who, if (!SCHEME_FFIANYPTRP(val)) { switch (CTYPE_PRIMLABEL(type)) { case FOREIGN_struct: - wrong_value(who, "(_struct ....)", val); + return wrong_value(who, "(_struct ....)", val); break; case FOREIGN_array: - wrong_value(who, "(_array ....)", val); + return wrong_value(who, "(_array ....)", val); break; default: case FOREIGN_union: - wrong_value(who, "(_union ....)", val); + return wrong_value(who, "(_union ....)", val); break; } } @@ -3472,7 +3494,7 @@ void scheme_init_foreign_globals() { @(maplines (lambda (x) (if (equal? (cadr x) "ctype") - @list{ctype_tag = scheme_ctype_type} + @list{} @list{@(cadr x)_tag = scheme_make_type("<@(car x)>")})) (reverse (cstructs))) @@IFDEF{MZ_PRECISE_GC}{ diff --git a/racket/src/foreign/rktc-utils.rkt b/racket/src/foreign/rktc-utils.rkt index 766e596b07..8b97f7e176 100644 --- a/racket/src/foreign/rktc-utils.rkt +++ b/racket/src/foreign/rktc-utils.rkt @@ -79,7 +79,7 @@ ;; Struct definitions (provide cstructs) (define cstructs (make-parameter '())) -(define (_cdefstruct name slots types) +(define (_cdefstruct name slots types #:tag [tag #f]) (define cname (regexp-replace* #rx"-" (symbol->string name) "_")) (define mname (string-upcase (regexp-replace* #rx"_" cname ""))) (define predname (string->symbol (format "~a?" name))) @@ -94,7 +94,9 @@ }}) (cstructs (cons (list* name cname slots) (cstructs))) @list{/* @name structure definition */ - static Scheme_Type @|cname|_tag; + @(if tag + @list{#define @|cname|_tag @tag} + @list{static Scheme_Type @|cname|_tag;}) typedef struct @|cname|_struct { Scheme_Object so; @(maplines (lambda (s t) @list{@t @s}) slots types) @@ -114,8 +116,8 @@ END_XFORM_SKIP; #endif}) (provide cdefstruct) -(define-syntax-rule (cdefstruct name [slot type] ...) - (_cdefstruct `name (list `slot ...) (list type ...))) +(define-syntax-rule (cdefstruct name [arg ...] [slot type] ...) + (_cdefstruct `name (list `slot ...) (list type ...) arg ...)) ;; Tagged object allocation (define (_cmake var type . values) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index c569fd218f..b42414b727 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -341,6 +341,7 @@ struct scheme_jit_common_record { void *bad_app_vals_target; void *app_values_slow_code, *app_values_multi_slow_code, *app_values_tail_slow_code; void *bad_char_to_integer_code, *slow_integer_to_char_code; + void *slow_cpointer_tag_code, *slow_set_cpointer_tag_code; void *values_code; void *list_p_code, *list_p_branch_code; void *list_length_code; diff --git a/racket/src/racket/src/jit_ts.c b/racket/src/racket/src/jit_ts.c index 755fc8a38d..4b5525cae6 100644 --- a/racket/src/racket/src/jit_ts.c +++ b/racket/src/racket/src/jit_ts.c @@ -112,6 +112,8 @@ define_ts_iS_s(scheme_check_not_undefined, FSRC_MARKS) define_ts_iS_s(scheme_check_assign_not_undefined, FSRC_MARKS) define_ts_iS_s(scheme_foreign_ptr_ref, FSRC_MARKS) define_ts_iS_v(scheme_foreign_ptr_set, FSRC_MARKS) +define_ts_s_s(scheme_cpointer_tag, FSRC_MARKS) +define_ts_ss_v(scheme_set_cpointer_tag, FSRC_MARKS) #endif #ifdef JITCALL_TS_PROCS @@ -250,4 +252,6 @@ define_ts_s_s(scheme_box, FSRC_OTHER) # define ts_scheme_check_assign_not_undefined scheme_check_assign_not_undefined # define ts_scheme_foreign_ptr_ref scheme_foreign_ptr_ref # define ts_scheme_foreign_ptr_set scheme_foreign_ptr_set +# define ts_scheme_cpointer_tag scheme_cpointer_tag +# define ts_scheme_set_cpointer_tag scheme_set_cpointer_tag #endif diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 2ab2e1c1d3..e0f1fcfe30 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -3332,6 +3332,30 @@ static int common13(mz_jit_state *jitter, void *_data) scheme_jit_register_sub_func(jitter, sjc.slow_ptr_set_code, scheme_false); CHECK_LIMIT(); + /* *** slow_cpointer_tag_code *** */ + sjc.slow_cpointer_tag_code = jit_get_ip(); + mz_prolog(JIT_R2); + JIT_UPDATE_THREAD_RSPTR(); + mz_prepare(1); + jit_pusharg_p(JIT_R0); + mz_finish_prim_lwe(ts_scheme_cpointer_tag, refr); + jit_retval(JIT_R0); + mz_epilog(JIT_R2); + scheme_jit_register_sub_func(jitter, sjc.slow_cpointer_tag_code, scheme_false); + CHECK_LIMIT(); + + /* *** slow_cpointer_tag_code *** */ + sjc.slow_set_cpointer_tag_code = jit_get_ip(); + mz_prolog(JIT_R2); + JIT_UPDATE_THREAD_RSPTR(); + mz_prepare(2); + jit_pusharg_p(JIT_R1); + jit_pusharg_p(JIT_R0); + mz_finish_prim_lwe(ts_scheme_set_cpointer_tag, refr); + mz_epilog(JIT_R2); + scheme_jit_register_sub_func(jitter, sjc.slow_set_cpointer_tag_code, scheme_false); + CHECK_LIMIT(); + /* *** force_value_same_mark_code *** */ /* Helper for futures: a synthetic functon that just forces values, which will bounce back to the runtime thread (but with lightweight diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 77ef1fc1a5..e35505b524 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -1975,6 +1975,39 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_patch_ucbranch(refdone); __END_TINY_JUMPS__(1); + return 1; + } else if (IS_NAMED_PRIM(rator, "cpointer-tag")) { + GC_CAN_IGNORE jit_insn *ref, *refslow, *refdone; + + mz_runstack_skipped(jitter, 1); + scheme_generate_non_tail(app->rand, jitter, 0, 1, 0); + CHECK_LIMIT(); + mz_runstack_unskipped(jitter, 1); + + mz_rs_sync(); + + __START_TINY_JUMPS__(1); + + ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); + refslow = jit_get_ip(); + __END_TINY_JUMPS__(1); + (void)jit_calli(sjc.slow_cpointer_tag_code); + __START_TINY_JUMPS__(1); + jit_movr_p(dest, JIT_R0); + refdone = jit_jmpi(jit_forward()); + mz_patch_branch(ref); + (void)mz_bnei_t(refslow, JIT_R0, scheme_cpointer_type, JIT_R1); + CHECK_LIMIT(); + + jit_ldxi_p(dest, JIT_R0, (intptr_t)&SCHEME_CPTR_TYPE((Scheme_Object *)0x0)); + ref = jit_bnei_p(jit_forward(), dest, NULL); + (void)jit_movi_p(dest, scheme_false); + mz_patch_branch(ref); + CHECK_LIMIT(); + + mz_patch_ucbranch(refdone); + __END_TINY_JUMPS__(1); + return 1; } else if (IS_NAMED_PRIM(rator, "future?")) { generate_inlined_type_test(jitter, app, scheme_future_type, scheme_future_type, 1, for_branch, branch_short, need_sync, dest); @@ -3664,6 +3697,35 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_retval(dest); CHECK_LIMIT(); + return 1; + } else if (IS_NAMED_PRIM(rator, "set-cpointer-tag!")) { + GC_CAN_IGNORE jit_insn *ref, *refslow, *refdone; + + LOG_IT(("inlined set-cpointer-tag!\n")); + + scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2); + CHECK_LIMIT(); + + __START_TINY_JUMPS__(1); + + ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); + refslow = jit_get_ip(); + __END_TINY_JUMPS__(1); + (void)jit_calli(sjc.slow_set_cpointer_tag_code); + __START_TINY_JUMPS__(1); + refdone = jit_jmpi(jit_forward()); + mz_patch_branch(ref); + (void)mz_bnei_t(refslow, JIT_R0, scheme_cpointer_type, JIT_R1); + CHECK_LIMIT(); + + jit_stxi_p((intptr_t)&SCHEME_CPTR_TYPE((Scheme_Object *)0x0), JIT_R0, JIT_R1); + + mz_patch_ucbranch(refdone); + __END_TINY_JUMPS__(1); + + if (!result_ignored) + (void)jit_movi_p(dest, scheme_void); + return 1; } } diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 3099f85466..0ac3d884b8 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -664,6 +664,9 @@ XFORM_NONGCING extern void *scheme_extract_pointer(Scheme_Object *v); Scheme_Object *scheme_foreign_ptr_ref(int argc, Scheme_Object **argv); void scheme_foreign_ptr_set(int argc, Scheme_Object **argv); +Scheme_Object *scheme_cpointer_tag(Scheme_Object *ptr); +void scheme_set_cpointer_tag(Scheme_Object *ptr, Scheme_Object *val); + void scheme_kickoff_green_thread_time_slice_timer(intptr_t usec); #ifdef UNIX_PROCESSES From 0480f55f67c111142c113185101fc428652f4176 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 5 Aug 2015 07:26:33 -0600 Subject: [PATCH 003/381] add `with-immediate-continuation-mark` bytecode form Specialize a (call-with-immediate-continuation-mark _key (lambda (_arg) _body) _def-val) call to an internal (with-immediate-continuation-mark [_arg (#%immediate _key _def_val)] _body) form, which avoids a closure allocation and more. This optimization is useful for contracts, which use `call-with-immediate-continuation-mark` to avoid redundant contract checks. --- racket/src/racket/src/compile.c | 16 +- racket/src/racket/src/eval.c | 29 ++ racket/src/racket/src/fun.c | 70 ++-- racket/src/racket/src/jit.c | 30 ++ racket/src/racket/src/jit.h | 1 + racket/src/racket/src/jit_ts.c | 2 + racket/src/racket/src/jitcommon.c | 17 + racket/src/racket/src/jitinline.c | 28 +- racket/src/racket/src/jitprep.c | 25 ++ racket/src/racket/src/jitstate.c | 4 + racket/src/racket/src/letrec_check.c | 3 + racket/src/racket/src/marshal.c | 38 +++ racket/src/racket/src/optimize.c | 123 +++++++ racket/src/racket/src/resolve.c | 29 ++ racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schpriv.h | 4 + racket/src/racket/src/schvers.h | 4 +- racket/src/racket/src/sfs.c | 58 ++++ racket/src/racket/src/stypes.h | 493 ++++++++++++++------------- racket/src/racket/src/type.c | 2 + racket/src/racket/src/validate.c | 30 ++ 21 files changed, 718 insertions(+), 290 deletions(-) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 9c0200438b..029ac93d48 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -1915,6 +1915,20 @@ static Scheme_Object *shift_compiled_expression(Scheme_Object *v, int delta, int v2 = shift_compiled_expression(SCHEME_PTR2_VAL(v), delta, skip); SCHEME_PTR2_VAL(v) = v2; + return v; + } + case scheme_with_immed_mark_type: + { + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)v; + Scheme_Object *v2; + + v2 = shift_compiled_expression(wcm->key, delta, skip); + wcm->key = v2; + v2 = shift_compiled_expression(wcm->val, delta, skip); + wcm->val = v2; + v2 = shift_compiled_expression(wcm->body, delta, skip+1); + wcm->body = v2; + return v; } case scheme_set_bang_type: @@ -5153,7 +5167,7 @@ compile_expand_app(Scheme_Object *orig_form, Scheme_Comp_Env *env, orig_rest_form = SCHEME_STX_CDR(form); - /* Look for (call-with-values (lambda () M) (lambda (id ...) N)) */ + /* Look for (call-with-values (lambda () M) (lambda (id ...) N)) */ if (SCHEME_STX_SYMBOLP(name)) { Scheme_Object *at_first, *at_second, *the_end; at_first = SCHEME_STX_CDR(form); diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 8c70198679..34fda3ec84 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -3827,6 +3827,35 @@ scheme_do_eval(Scheme_Object *obj, int num_rands, Scheme_Object **rands, v = apply_values_execute(obj); break; } + case scheme_with_immed_mark_type: + { +# define wcm ((Scheme_With_Continuation_Mark *)obj) + Scheme_Object *mark_key; + GC_CAN_IGNORE Scheme_Object *mark_val; + + mark_key = wcm->key; + if (SCHEME_TYPE(mark_key) < _scheme_values_types_) { + UPDATE_THREAD_RSPTR(); + mark_key = _scheme_eval_linked_expr_wp(mark_key, p); + } + + mark_val = wcm->val; + if (SCHEME_TYPE(mark_val) < _scheme_values_types_) { + UPDATE_THREAD_RSPTR(); + mark_val = _scheme_eval_linked_expr_wp(mark_val, p); + } + + UPDATE_THREAD_RSPTR(); + mark_val = scheme_chaperone_get_immediate_cc_mark(mark_key, mark_val); + + PUSH_RUNSTACK(p, RUNSTACK, 1); + RUNSTACK_CHANGED(); + RUNSTACK[0] = mark_val; + + obj = wcm->body; + goto eval_top; +#undef wcm + } case scheme_case_lambda_sequence_type: { UPDATE_THREAD_RSPTR(); diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index b10b57dea0..5c727d4af2 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -93,6 +93,7 @@ READ_ONLY Scheme_Object *scheme_check_not_undefined_proc; READ_ONLY Scheme_Object *scheme_check_assign_not_undefined_proc; READ_ONLY Scheme_Object *scheme_apply_proc; READ_ONLY Scheme_Object *scheme_call_with_values_proc; /* the function bound to `call-with-values' */ +READ_ONLY Scheme_Object *scheme_call_with_immed_mark_proc; READ_ONLY Scheme_Object *scheme_reduced_procedure_struct; READ_ONLY Scheme_Object *scheme_tail_call_waiting; READ_ONLY Scheme_Object *scheme_default_prompt_tag; @@ -483,11 +484,13 @@ scheme_init_fun (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(o) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_BINARY_INLINED); scheme_add_global_constant("continuation-mark-set-first", o, env); + REGISTER_SO(scheme_call_with_immed_mark_proc); + scheme_call_with_immed_mark_proc = scheme_make_prim_w_arity2(call_with_immediate_cc_mark, + "call-with-immediate-continuation-mark", + 2, 3, + 0, -1); scheme_add_global_constant("call-with-immediate-continuation-mark", - scheme_make_prim_w_arity2(call_with_immediate_cc_mark, - "call-with-immediate-continuation-mark", - 2, 3, - 0, -1), + scheme_call_with_immed_mark_proc, env); scheme_add_global_constant("continuation-mark-set?", scheme_make_prim_w_arity(cc_marks_p, @@ -4351,24 +4354,10 @@ static Scheme_Object *impersonate_continuation_mark_key(int argc, Scheme_Object return do_chaperone_continuation_mark_key("impersonate-continuation-mark-key", 1, argc, argv); } - -static Scheme_Object *call_with_immediate_cc_mark (int argc, Scheme_Object *argv[]) +Scheme_Object *scheme_get_immediate_cc_mark(Scheme_Object *key, Scheme_Object *def_val) { Scheme_Thread *p = scheme_current_thread; intptr_t findpos, bottom; - Scheme_Object *a[1], *key; - - scheme_check_proc_arity("call-with-immediate-continuation-mark", 1, 1, argc, argv); - - key = argv[0]; - if (SCHEME_NP_CHAPERONEP(key) - && SCHEME_CONTINUATION_MARK_KEYP(SCHEME_CHAPERONE_VAL(key))) - key = SCHEME_CHAPERONE_VAL(key); - - if (argc > 2) - a[0] = argv[2]; - else - a[0] = scheme_false; if (p->cont_mark_stack_segments) { findpos = (intptr_t)MZ_CONT_MARK_STACK; @@ -4381,23 +4370,40 @@ static Scheme_Object *call_with_immediate_cc_mark (int argc, Scheme_Object *argv if ((intptr_t)find->pos < (intptr_t)MZ_CONT_MARK_POS) { break; } else { - if (find->key == key) { - /* - * If not equal, it was a chaperone since we unwrapped the key - */ - if (argv[0] != key) { - Scheme_Object *val; - val = scheme_chaperone_do_continuation_mark("call-with-immediate-continuation-mark", - 1, argv[0], find->val); - a[0] = val; - } else - a[0] = find->val; - break; - } + if (find->key == key) + return find->val; } } } + return def_val; +} + +Scheme_Object *scheme_chaperone_get_immediate_cc_mark(Scheme_Object *key, Scheme_Object *def_val) +{ + Scheme_Object *val; + + if (SCHEME_NP_CHAPERONEP(key) + && SCHEME_CONTINUATION_MARK_KEYP(SCHEME_CHAPERONE_VAL(key))) { + val = scheme_get_immediate_cc_mark(SCHEME_CHAPERONE_VAL(key), NULL); + if (val) + return scheme_chaperone_do_continuation_mark("call-with-immediate-continuation-mark", + 1, key, val); + else + return def_val; + } else + return scheme_get_immediate_cc_mark(key, def_val); +} + +static Scheme_Object *call_with_immediate_cc_mark (int argc, Scheme_Object *argv[]) +{ + Scheme_Object *a[1], *val; + + scheme_check_proc_arity("call-with-immediate-continuation-mark", 1, 1, argc, argv); + + val = scheme_chaperone_get_immediate_cc_mark(argv[0], ((argc > 2) ? argv[2] : scheme_false)); + a[0] = val; + return scheme_tail_apply(argv[1], 1, a); } diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index ef7368731f..ad314afbf4 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -2445,6 +2445,36 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w return 1; } break; + case scheme_with_immed_mark_type: + { + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)obj; + START_JIT_DATA(); + + LOG_IT(("with-immediate-continuation-mark...\n")); + + scheme_generate_two_args(wcm->key, wcm->val, jitter, 1, 0); + CHECK_LIMIT(); + + /* key is in JIT_R0, default value is in JIT_R1 */ + mz_rs_sync(); + + (void)jit_calli(sjc.with_immed_mark_code); + + mz_rs_dec(1); + CHECK_RUNSTACK_OVERFLOW(); + mz_runstack_pushed(jitter, 1); + mz_rs_str(JIT_R0); + + CHECK_LIMIT(); + + END_JIT_DATA(22); + + LOG_IT(("...in\n")); + + return scheme_generate(wcm->body, jitter, is_tail, wcm_may_replace, + multi_ok, orig_target, for_branch); + } + break; case scheme_boxenv_type: { Scheme_Object *p, *v; diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index b42414b727..86db646ac1 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -356,6 +356,7 @@ struct scheme_jit_common_record { void *box_extflonum_from_stack_code, *box_extflonum_from_reg_code; #endif void *wcm_code, *wcm_nontail_code, *wcm_chaperone; + void *with_immed_mark_code; void *apply_to_list_tail_code, *apply_to_list_code, *apply_to_list_multi_ok_code; void *eqv_code, *eqv_branch_code; void *proc_arity_includes_code; diff --git a/racket/src/racket/src/jit_ts.c b/racket/src/racket/src/jit_ts.c index 4b5525cae6..326557f752 100644 --- a/racket/src/racket/src/jit_ts.c +++ b/racket/src/racket/src/jit_ts.c @@ -103,6 +103,7 @@ define_ts_iSs_s(scheme_struct_getter, FSRC_MARKS) define_ts_iSs_s(scheme_struct_setter, FSRC_MARKS) define_ts_iS_s(scheme_box_cas, FSRC_MARKS) define_ts__v(chaperone_set_mark, FSRC_MARKS) +define_ts_ss_s(scheme_chaperone_get_immediate_cc_mark, FSRC_MARKS) define_ts_iS_s(scheme_checked_char_to_integer, FSRC_MARKS) define_ts_iS_s(scheme_checked_integer_to_char, FSRC_MARKS) # ifndef CAN_INLINE_ALLOC @@ -205,6 +206,7 @@ define_ts_s_s(scheme_box, FSRC_OTHER) # define ts_scheme_set_box scheme_set_box # define ts_scheme_box_cas scheme_box_cas # define ts_chaperone_set_mark chaperone_set_mark +# define ts_scheme_chaperone_get_immediate_cc_mark scheme_chaperone_get_immediate_cc_mark # define ts_scheme_vector_length scheme_vector_length # define ts_scheme_flvector_length scheme_flvector_length #ifdef MZ_LONG_DOUBLE diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index e0f1fcfe30..30cec6dc42 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -2711,6 +2711,23 @@ static int common6(mz_jit_state *jitter, void *_data) scheme_jit_register_sub_func(jitter, sjc.wcm_chaperone, scheme_false); } + /* with_immed_mark_code */ + { + GC_CAN_IGNORE jit_insn *ref2 USED_ONLY_FOR_FUTURES; + sjc.with_immed_mark_code = jit_get_ip(); + + mz_prolog(JIT_R2); + JIT_UPDATE_THREAD_RSPTR(); + jit_prepare(2); + jit_pusharg_p(JIT_R1); + jit_pusharg_p(JIT_R0); + (void)mz_finish_lwe(ts_scheme_chaperone_get_immediate_cc_mark, ref2); + jit_retval(JIT_R0); + mz_epilog(JIT_R2); + + scheme_jit_register_sub_func(jitter, sjc.with_immed_mark_code, scheme_false); + } + return 1; } diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index e35505b524..22a667d228 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -2130,24 +2130,36 @@ int scheme_generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW(); - mz_runstack_pushed(jitter, 1); - mz_rs_str(JIT_R0); - mz_runstack_skipped(jitter, skipped-1); + if (skipped) { + mz_runstack_pushed(jitter, 1); + mz_rs_str(JIT_R0); + mz_runstack_skipped(jitter, skipped-1); + } else { + mz_pushr_p(JIT_R0); + } scheme_generate_non_tail(rand2, jitter, 0, 1, 0); /* no sync... */ CHECK_LIMIT(); if (order_matters) { jit_movr_p(JIT_R1, JIT_R0); - mz_rs_ldr(JIT_R0); + if (!skipped) + mz_popr_p(JIT_R0); + else + mz_rs_ldr(JIT_R0); } else { - mz_rs_ldr(JIT_R1); + if (!skipped) + mz_popr_p(JIT_R1); + else + mz_rs_ldr(JIT_R1); direction = -1; } - mz_runstack_unskipped(jitter, skipped-1); - mz_rs_inc(1); - mz_runstack_popped(jitter, 1); + if (skipped) { + mz_runstack_unskipped(jitter, skipped-1); + mz_rs_inc(1); + mz_runstack_popped(jitter, 1); + } } } else { mz_runstack_skipped(jitter, skipped); diff --git a/racket/src/racket/src/jitprep.c b/racket/src/racket/src/jitprep.c index 2b79c51864..dc64a18ebe 100644 --- a/racket/src/racket/src/jitprep.c +++ b/racket/src/racket/src/jitprep.c @@ -379,6 +379,29 @@ static Scheme_Object *apply_values_jit(Scheme_Object *data) } } +static Scheme_Object *with_immed_mark_jit(Scheme_Object *o) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)o; + Scheme_Object *k, *v, *b; + + k = scheme_jit_expr(wcm->key); + v = scheme_jit_expr(wcm->val); + b = scheme_jit_expr(wcm->body); + if (SAME_OBJ(wcm->key, k) + && SAME_OBJ(wcm->val, v) + && SAME_OBJ(wcm->body, b)) + return o; + + wcm = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); + memcpy(wcm, o, sizeof(Scheme_With_Continuation_Mark)); + + wcm->key = k; + wcm->val = v; + wcm->body = b; + + return (Scheme_Object *)wcm; +} + Scheme_Object *scheme_case_lambda_jit(Scheme_Object *expr) { #ifdef MZ_USE_JIT @@ -625,6 +648,8 @@ Scheme_Object *scheme_jit_expr(Scheme_Object *expr) return ref_jit(expr); case scheme_apply_values_type: return apply_values_jit(expr); + case scheme_with_immed_mark_type: + return with_immed_mark_jit(expr); case scheme_case_lambda_sequence_type: return scheme_case_lambda_jit(expr); case scheme_module_type: diff --git a/racket/src/racket/src/jitstate.c b/racket/src/racket/src/jitstate.c index 1f5a338828..6d6e6fbabf 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -545,6 +545,8 @@ void scheme_mz_runstack_skipped(mz_jit_state *jitter, int n) { int v; + if (!n) return; + if (!(jitter->mappings[jitter->num_mappings] & 0x1) || (jitter->mappings[jitter->num_mappings] & 0x2) || (jitter->mappings[jitter->num_mappings] > 0)) { @@ -561,6 +563,8 @@ void scheme_mz_runstack_unskipped(mz_jit_state *jitter, int n) { int v; + if (!n) return; + JIT_ASSERT(jitter->mappings[jitter->num_mappings] & 0x1); JIT_ASSERT(!(jitter->mappings[jitter->num_mappings] & 0x2)); v = (jitter->mappings[jitter->num_mappings]) >> 2; diff --git a/racket/src/racket/src/letrec_check.c b/racket/src/racket/src/letrec_check.c index f3ad9c9da1..74c84f2317 100644 --- a/racket/src/racket/src/letrec_check.c +++ b/racket/src/racket/src/letrec_check.c @@ -1083,6 +1083,9 @@ static Scheme_Object *letrec_check_expr(Scheme_Object *expr, Letrec_Check_Frame return letrec_check_begin0(expr, frame, pos); case scheme_apply_values_type: return letrec_check_apply_values(expr, frame, pos); + case scheme_with_immed_mark_type: + scheme_signal_error("internal error: with-immediate-mark not expected before optimization"); + return NULL; case scheme_require_form_type: return expr; case scheme_module_type: diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 32073b7940..60ef95c1f6 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -55,6 +55,8 @@ static Scheme_Object *read_varref(Scheme_Object *obj); static Scheme_Object *write_varref(Scheme_Object *obj); static Scheme_Object *read_apply_values(Scheme_Object *obj); static Scheme_Object *write_apply_values(Scheme_Object *obj); +static Scheme_Object *read_with_immed_mark(Scheme_Object *obj); +static Scheme_Object *write_with_immed_mark(Scheme_Object *obj); static Scheme_Object *read_inline_variant(Scheme_Object *obj); static Scheme_Object *write_inline_variant(Scheme_Object *obj); @@ -137,6 +139,8 @@ void scheme_init_marshal(Scheme_Env *env) scheme_install_type_reader(scheme_varref_form_type, read_varref); scheme_install_type_writer(scheme_apply_values_type, write_apply_values); scheme_install_type_reader(scheme_apply_values_type, read_apply_values); + scheme_install_type_writer(scheme_with_immed_mark_type, write_with_immed_mark); + scheme_install_type_reader(scheme_with_immed_mark_type, read_with_immed_mark); scheme_install_type_writer(scheme_inline_variant_type, write_inline_variant); scheme_install_type_reader(scheme_inline_variant_type, read_inline_variant); @@ -512,6 +516,40 @@ Scheme_Object *read_apply_values(Scheme_Object *o) return data; } +Scheme_Object *write_with_immed_mark(Scheme_Object *o) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)o; + Scheme_Object *vec, *v; + + vec = scheme_make_vector(3, NULL); + + v = scheme_protect_quote(wcm->key); + SCHEME_VEC_ELS(vec)[0] = v; + v = scheme_protect_quote(wcm->val); + SCHEME_VEC_ELS(vec)[1] = v; + v = scheme_protect_quote(wcm->body); + SCHEME_VEC_ELS(vec)[2] = v; + + return vec; +} + +Scheme_Object *read_with_immed_mark(Scheme_Object *o) +{ + Scheme_With_Continuation_Mark *wcm; + + if (!SCHEME_VECTORP(o)) return NULL; + if (SCHEME_VEC_SIZE(o) != 3) return NULL; + + wcm = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); + wcm->so.type = scheme_with_immed_mark_type; + + wcm->key = SCHEME_VEC_ELS(o)[0]; + wcm->val = SCHEME_VEC_ELS(o)[1]; + wcm->body = SCHEME_VEC_ELS(o)[2]; + + return (Scheme_Object *)wcm; +} + Scheme_Object *write_boxenv(Scheme_Object *o) { return scheme_make_pair(SCHEME_PTR1_VAL(o), SCHEME_PTR2_VAL(o)); diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index f1f9b1b560..e3ae38b326 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -2686,6 +2686,31 @@ static Scheme_Object *direct_apply(Scheme_Object *expr, Scheme_Object *rator, Sc return NULL; } +static Scheme_Object *call_with_immed_mark(Scheme_Object *rator, + Scheme_Object *rand1, + Scheme_Object *rand2, + Scheme_Object *rand3, + Optimize_Info *info) +{ + if (SAME_OBJ(rator, scheme_call_with_immed_mark_proc) + && SAME_TYPE(SCHEME_TYPE(rand2), scheme_compiled_unclosed_procedure_type) + && (((Scheme_Closure_Data *)rand2)->num_params == 1) + && !(SCHEME_CLOSURE_DATA_FLAGS(((Scheme_Closure_Data *)rand2)) & CLOS_HAS_REST)) { + Scheme_With_Continuation_Mark *wcm; + + wcm = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); + wcm->so.type = scheme_with_immed_mark_type; + + wcm->key = rand1; + wcm->val = (rand3 ? rand3 : scheme_false); + wcm->body = ((Scheme_Closure_Data *)rand2)->code; + + return (Scheme_Object *)wcm; + } + + return NULL; +} + static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info, int context) { Scheme_Object *le; @@ -2700,6 +2725,12 @@ static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info if (le) return scheme_optimize_expr(le, info, context); + if (app->num_args == 3) { + le = call_with_immed_mark(app->args[0], app->args[1], app->args[2], app->args[3], info); + if (le) + return scheme_optimize_expr(le, info, context); + } + le = check_app_let_rator(o, app->args[0], info, app->num_args, context); if (le) return le; @@ -3370,6 +3401,10 @@ static Scheme_Object *optimize_application3(Scheme_Object *o, Optimize_Info *inf if (le) return scheme_optimize_expr(le, info, context); + le = call_with_immed_mark(app->rator, app->rand1, app->rand2, NULL, info); + if (le) + return scheme_optimize_expr(le, info, context); + le = check_app_let_rator(o, app->rator, info, 2, context); if (le) return le; @@ -4690,6 +4725,88 @@ apply_values_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int del return data; } +static Scheme_Object * +with_immed_mark_optimize(Scheme_Object *data, Optimize_Info *info, int context) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)data; + Scheme_Object *key, *val, *body; + Optimize_Info_Sequence info_seq; + Optimize_Info *body_info; + + optimize_info_seq_init(info, &info_seq); + + key = scheme_optimize_expr(wcm->key, info, OPT_CONTEXT_SINGLED); + optimize_info_seq_step(info, &info_seq); + if (info->escapes) { + optimize_info_seq_done(info, &info_seq); + return key; + } + + val = scheme_optimize_expr(wcm->val, info, OPT_CONTEXT_SINGLED); + optimize_info_seq_step(info, &info_seq); + if (info->escapes) { + optimize_info_seq_done(info, &info_seq); + return make_discarding_first_sequence(key, val, info, 0); + } + + optimize_info_seq_done(info, &info_seq); + + body_info = optimize_info_add_frame(info, 1, 1, 0); + + body = scheme_optimize_expr(wcm->body, body_info, 0); + + optimize_info_done(body_info, NULL); + + wcm->key = key; + wcm->val = val; + wcm->body = body; + + return data; +} + +static Scheme_Object * +with_immed_mark_shift(Scheme_Object *data, int delta, int after_depth) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)data; + Scheme_Object *e; + + e = optimize_shift(wcm->key, delta, after_depth); + wcm->key = e; + + e = optimize_shift(wcm->val, delta, after_depth); + wcm->val = e; + + e = optimize_shift(wcm->body, delta, after_depth+1); + wcm->body = e; + + return data; +} + +static Scheme_Object * +with_immed_mark_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)data; + Scheme_With_Continuation_Mark *wcm2; + Scheme_Object *e; + + wcm2 = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); + wcm2->so.type = scheme_with_immed_mark_type; + + e = optimize_clone(dup_ok, wcm->key, info, delta, closure_depth); + if (!e) return NULL; + wcm2->key = e; + + e = optimize_clone(dup_ok, wcm->val, info, delta, closure_depth); + if (!e) return NULL; + wcm2->val = e; + + e = optimize_clone(dup_ok, wcm->body, info, delta, closure_depth+1); + if (!e) return NULL; + wcm2->body = e; + + return (Scheme_Object *)wcm2; +} + static Scheme_Object * case_lambda_optimize(Scheme_Object *expr, Optimize_Info *info, int context) { @@ -7624,6 +7741,8 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info, in return begin0_optimize(expr, info, context); case scheme_apply_values_type: return apply_values_optimize(expr, info, context); + case scheme_with_immed_mark_type: + return with_immed_mark_optimize(expr, info, context); case scheme_require_form_type: return top_level_require_optimize(expr, info, context); case scheme_module_type: @@ -7856,6 +7975,8 @@ Scheme_Object *optimize_clone(int dup_ok, Scheme_Object *expr, Optimize_Info *in return set_clone(dup_ok, expr, info, delta, closure_depth); case scheme_apply_values_type: return apply_values_clone(dup_ok, expr, info, delta, closure_depth); + case scheme_with_immed_mark_type: + return with_immed_mark_clone(dup_ok, expr, info, delta, closure_depth); case scheme_case_lambda_sequence_type: return case_lambda_clone(dup_ok, expr, info, delta, closure_depth); case scheme_module_type: @@ -8011,6 +8132,8 @@ Scheme_Object *optimize_shift(Scheme_Object *expr, int delta, int after_depth) return ref_shift(expr, delta, after_depth); case scheme_apply_values_type: return apply_values_shift(expr, delta, after_depth); + case scheme_with_immed_mark_type: + return with_immed_mark_shift(expr, delta, after_depth); case scheme_case_lambda_sequence_type: return case_lambda_shift(expr, delta, after_depth); case scheme_boxenv_type: diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 0d5ab6f2e8..20d4a1752b 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -717,6 +717,33 @@ apply_values_resolve(Scheme_Object *data, Resolve_Info *rslv) return data; } +static Scheme_Object * +with_immed_mark_resolve(Scheme_Object *data, Resolve_Info *orig_rslv) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)data; + Scheme_Object *e; + Resolve_Info *rslv = orig_rslv; + + e = scheme_resolve_expr(wcm->key, rslv); + wcm->key = e; + + e = scheme_resolve_expr(wcm->val, rslv); + wcm->val = e; + + rslv = resolve_info_extend(rslv, 1, 1, 1); + resolve_info_add_mapping(rslv, 0, 0, 0, NULL); + + e = scheme_resolve_expr(wcm->body, rslv); + wcm->body = e; + + rslv->max_let_depth += 1; + if (orig_rslv->max_let_depth < rslv->max_let_depth) + orig_rslv->max_let_depth = rslv->max_let_depth; + merge_resolve_tl_map(orig_rslv, rslv); + + return data; +} + static Scheme_Object * case_lambda_resolve(Scheme_Object *expr, Resolve_Info *rslv) { @@ -2521,6 +2548,8 @@ Scheme_Object *scheme_resolve_expr(Scheme_Object *expr, Resolve_Info *info) return ref_resolve(expr, info); case scheme_apply_values_type: return apply_values_resolve(expr, info); + case scheme_with_immed_mark_type: + return with_immed_mark_resolve(expr, info); case scheme_case_lambda_sequence_type: return case_lambda_resolve(expr, info); case scheme_module_type: diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 0e2a470120..1427fad91f 100644 --- a/racket/src/racket/src/schminc.h +++ b/racket/src/racket/src/schminc.h @@ -12,7 +12,7 @@ finally, set EXPECTED_PRIM_COUNT to the right value and USE_COMPILED_STARTUP to 1 and `make' again. */ -#define USE_COMPILED_STARTUP 1 +#define USE_COMPILED_STARTUP 0 #define EXPECTED_PRIM_COUNT 1134 #define EXPECTED_UNSAFE_COUNT 106 diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 0ac3d884b8..94c66c80b7 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -472,6 +472,7 @@ extern Scheme_Object *scheme_box_p_proc; extern Scheme_Object *scheme_box_proc; extern Scheme_Object *scheme_box_immutable_proc; extern Scheme_Object *scheme_call_with_values_proc; +extern Scheme_Object *scheme_call_with_immed_mark_proc; extern Scheme_Object *scheme_make_struct_type_proc; extern Scheme_Object *scheme_make_struct_field_accessor_proc; extern Scheme_Object *scheme_make_struct_field_mutator_proc; @@ -1906,6 +1907,9 @@ Scheme_Object *scheme_jump_to_continuation(Scheme_Object *obj, int num_rands, Sc Scheme_Object *scheme_chaperone_do_continuation_mark(const char *name, int is_get, Scheme_Object *key, Scheme_Object *val); +XFORM_NONGCING Scheme_Object *scheme_get_immediate_cc_mark(Scheme_Object *key, Scheme_Object *def_val); +Scheme_Object *scheme_chaperone_get_immediate_cc_mark(Scheme_Object *key, Scheme_Object *def_val); + /*========================================================================*/ /* semaphores and locks */ /*========================================================================*/ diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 98eab0e1b4..1e2fb67314 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.6" +#define MZSCHEME_VERSION "6.2.900.7" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 6 +#define MZSCHEME_VERSION_W 7 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/sfs.c b/racket/src/racket/src/sfs.c index dc0318dc70..3f551f4b1a 100644 --- a/racket/src/racket/src/sfs.c +++ b/racket/src/racket/src/sfs.c @@ -905,6 +905,61 @@ apply_values_sfs(Scheme_Object *data, SFS_Info *info) return data; } +static Scheme_Object *with_immed_mark_sfs(Scheme_Object *o, SFS_Info *info) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)o; + Scheme_Object *k, *v, *b, *vec; + int pos, save_mnt, ip; + + scheme_sfs_start_sequence(info, 3, 1); + + k = scheme_sfs_expr(wcm->key, info, -1); + v = scheme_sfs_expr(wcm->val, info, -1); + + scheme_sfs_push(info, 1, 1); + + ip = info->ip; + pos = info->stackpos; + save_mnt = info->max_nontail; + + if (!info->pass) { + vec = scheme_make_vector(3, NULL); + scheme_sfs_save(info, vec); + } else { + vec = scheme_sfs_next_saved(info); + if (SCHEME_VEC_SIZE(vec) != 3) + scheme_signal_error("internal error: bad vector length"); + info->max_used[pos] = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[0]); + info->max_calls[pos] = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[1]); + info->max_nontail = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[2]); + } + + b = scheme_sfs_expr(wcm->body, info, -1); + + wcm->key = k; + wcm->val = v; + wcm->body = b; + +# if MAX_SFS_CLEARING + if (!info->pass) + info->max_nontail = info->ip; +# endif + + if (!info->pass) { + int n; + info->max_calls[pos] = info->max_nontail; + n = info->max_used[pos]; + SCHEME_VEC_ELS(vec)[0] = scheme_make_integer(n); + n = info->max_calls[pos]; + SCHEME_VEC_ELS(vec)[1] = scheme_make_integer(n); + SCHEME_VEC_ELS(vec)[2] = scheme_make_integer(info->max_nontail); + } else { + info->max_nontail = save_mnt; + } + + return o; +} + static Scheme_Object * case_lambda_sfs(Scheme_Object *expr, SFS_Info *info) { @@ -1336,6 +1391,9 @@ Scheme_Object *scheme_sfs_expr(Scheme_Object *expr, SFS_Info *info, int closure_ case scheme_apply_values_type: expr = apply_values_sfs(expr, info); break; + case scheme_with_immed_mark_type: + expr = with_immed_mark_sfs(expr, info); + break; case scheme_case_lambda_sequence_type: expr = case_lambda_sfs(expr, info); break; diff --git a/racket/src/racket/src/stypes.h b/racket/src/racket/src/stypes.h index 8a0ed41ec3..68b9530d19 100644 --- a/racket/src/racket/src/stypes.h +++ b/racket/src/racket/src/stypes.h @@ -28,278 +28,279 @@ enum { scheme_require_form_type, /* 22 */ scheme_varref_form_type, /* 23 */ scheme_apply_values_type, /* 24 */ - scheme_case_lambda_sequence_type, /* 25 */ - scheme_module_type, /* 26 */ - scheme_inline_variant_type, /* 27 */ + scheme_with_immed_mark_type, /* 25 */ + scheme_case_lambda_sequence_type, /* 26 */ + scheme_module_type, /* 27 */ + scheme_inline_variant_type, /* 28 */ _scheme_values_types_, /* All following types are values */ /* intermediate compiled: */ - scheme_compiled_unclosed_procedure_type,/* 29 */ - scheme_compiled_let_value_type, /* 30 */ - scheme_compiled_let_void_type, /* 31 */ - scheme_compiled_toplevel_type, /* 32 */ - scheme_compiled_quote_syntax_type, /* 33 */ + scheme_compiled_unclosed_procedure_type,/* 30 */ + scheme_compiled_let_value_type, /* 31 */ + scheme_compiled_let_void_type, /* 32 */ + scheme_compiled_toplevel_type, /* 33 */ + scheme_compiled_quote_syntax_type, /* 34 */ scheme_quote_compilation_type, /* used while writing, only */ /* Registered in prefix table: */ - scheme_variable_type, /* 35 */ + scheme_variable_type, /* 36 */ scheme_module_variable_type, /* link replaces with scheme_variable_type */ - _scheme_compiled_values_types_, /* 37 */ + _scheme_compiled_values_types_, /* 38 */ /* procedure types */ - scheme_prim_type, /* 38 */ - scheme_closed_prim_type, /* 39 */ - scheme_closure_type, /* 40 */ - scheme_case_closure_type, /* 41 */ - scheme_cont_type, /* 42 */ - scheme_escaping_cont_type, /* 43 */ - scheme_proc_struct_type, /* 44 */ - scheme_native_closure_type, /* 45 */ - scheme_proc_chaperone_type, /* 46 */ + scheme_prim_type, /* 39 */ + scheme_closed_prim_type, /* 40 */ + scheme_closure_type, /* 41 */ + scheme_case_closure_type, /* 42 */ + scheme_cont_type, /* 43 */ + scheme_escaping_cont_type, /* 44 */ + scheme_proc_struct_type, /* 45 */ + scheme_native_closure_type, /* 46 */ + scheme_proc_chaperone_type, /* 47 */ - scheme_chaperone_type, /* 47 */ + scheme_chaperone_type, /* 48 */ /* structure type (plus one above for procs) */ - scheme_structure_type, /* 48 */ + scheme_structure_type, /* 49 */ /* number types (must be together) */ - scheme_integer_type, /* 49 */ - scheme_bignum_type, /* 50 */ - scheme_rational_type, /* 51 */ - scheme_float_type, /* 52 */ - scheme_double_type, /* 53 */ - scheme_complex_type, /* 54 */ + scheme_integer_type, /* 50 */ + scheme_bignum_type, /* 51 */ + scheme_rational_type, /* 52 */ + scheme_float_type, /* 53 */ + scheme_double_type, /* 54 */ + scheme_complex_type, /* 55 */ /* other eqv?-able values (must be with numbers) */ - scheme_char_type, /* 55 */ + scheme_char_type, /* 56 */ /* other values */ - scheme_long_double_type, /* 56 */ - scheme_char_string_type, /* 57 */ - scheme_byte_string_type, /* 58 */ - scheme_unix_path_type, /* 59 */ - scheme_windows_path_type, /* 60 */ - scheme_symbol_type, /* 61 */ - scheme_keyword_type, /* 62 */ - scheme_null_type, /* 63 */ - scheme_pair_type, /* 64 */ - scheme_mutable_pair_type, /* 65 */ - scheme_vector_type, /* 66 */ - scheme_inspector_type, /* 67 */ - scheme_input_port_type, /* 68 */ - scheme_output_port_type, /* 69 */ - scheme_eof_type, /* 70 */ - scheme_true_type, /* 71 */ - scheme_false_type, /* 72 */ - scheme_void_type, /* 73 */ - scheme_syntax_compiler_type, /* 74 */ - scheme_macro_type, /* 75 */ - scheme_box_type, /* 76 */ - scheme_thread_type, /* 77 */ - scheme_scope_type, /* 78 */ - scheme_stx_offset_type, /* 79 */ - scheme_cont_mark_set_type, /* 80 */ - scheme_sema_type, /* 81 */ - scheme_hash_table_type, /* 82 */ - scheme_hash_tree_type, /* 83 */ - scheme_eq_hash_tree_type, /* 84 */ - scheme_eqv_hash_tree_type, /* 85 */ - scheme_hash_tree_subtree_type, /* 86 */ - scheme_hash_tree_collision_type, /* 87 */ - scheme_hash_tree_indirection_type, /* 88 */ - scheme_cpointer_type, /* 89 */ - scheme_prefix_type, /* 90 */ - scheme_weak_box_type, /* 91 */ - scheme_ephemeron_type, /* 92 */ - scheme_struct_type_type, /* 93 */ - scheme_module_index_type, /* 94 */ - scheme_set_macro_type, /* 95 */ - scheme_listener_type, /* 96 */ - scheme_namespace_type, /* 97 */ - scheme_config_type, /* 98 */ - scheme_stx_type, /* 99 */ - scheme_will_executor_type, /* 100 */ - scheme_custodian_type, /* 101 */ - scheme_random_state_type, /* 102 */ - scheme_regexp_type, /* 103 */ - scheme_bucket_type, /* 104 */ - scheme_bucket_table_type, /* 105 */ - scheme_subprocess_type, /* 106 */ - scheme_compilation_top_type, /* 107 */ - scheme_wrap_chunk_type, /* 108 */ - scheme_eval_waiting_type, /* 109 */ - scheme_tail_call_waiting_type, /* 110 */ - scheme_undefined_type, /* 111 */ - scheme_struct_property_type, /* 112 */ - scheme_chaperone_property_type, /* 113 */ - scheme_multiple_values_type, /* 114 */ - scheme_placeholder_type, /* 115 */ - scheme_table_placeholder_type, /* 116 */ - scheme_scope_table_type, /* 117 */ - scheme_propagate_table_type, /* 118 */ - scheme_svector_type, /* 119 */ - scheme_resolve_prefix_type, /* 120 */ - scheme_security_guard_type, /* 121 */ - scheme_indent_type, /* 122 */ - scheme_udp_type, /* 123 */ - scheme_udp_evt_type, /* 124 */ - scheme_tcp_accept_evt_type, /* 125 */ - scheme_id_macro_type, /* 126 */ - scheme_evt_set_type, /* 127 */ - scheme_wrap_evt_type, /* 128 */ - scheme_handle_evt_type, /* 129 */ - scheme_replace_evt_type, /* 130 */ - scheme_active_replace_evt_type, /* 131 */ - scheme_nack_guard_evt_type, /* 132 */ - scheme_semaphore_repost_type, /* 133 */ - scheme_channel_type, /* 134 */ - scheme_channel_put_type, /* 135 */ - scheme_thread_resume_type, /* 136 */ - scheme_thread_suspend_type, /* 137 */ - scheme_thread_dead_type, /* 138 */ - scheme_poll_evt_type, /* 139 */ - scheme_nack_evt_type, /* 140 */ - scheme_module_registry_type, /* 141 */ - scheme_thread_set_type, /* 142 */ - scheme_string_converter_type, /* 143 */ - scheme_alarm_type, /* 144 */ - scheme_thread_recv_evt_type, /* 145 */ - scheme_thread_cell_type, /* 146 */ - scheme_channel_syncer_type, /* 147 */ - scheme_special_comment_type, /* 148 */ - scheme_write_evt_type, /* 149 */ - scheme_always_evt_type, /* 150 */ - scheme_never_evt_type, /* 151 */ - scheme_progress_evt_type, /* 152 */ - scheme_place_dead_type, /* 153 */ - scheme_already_comp_type, /* 154 */ - scheme_readtable_type, /* 155 */ - scheme_intdef_context_type, /* 156 */ - scheme_lexical_rib_type, /* 157 */ - scheme_thread_cell_values_type, /* 158 */ - scheme_global_ref_type, /* 159 */ - scheme_cont_mark_chain_type, /* 160 */ - scheme_raw_pair_type, /* 161 */ - scheme_prompt_type, /* 162 */ - scheme_prompt_tag_type, /* 163 */ - scheme_continuation_mark_key_type, /* 164 */ - scheme_expanded_syntax_type, /* 165 */ - scheme_delay_syntax_type, /* 166 */ - scheme_cust_box_type, /* 167 */ - scheme_resolved_module_path_type, /* 168 */ - scheme_module_phase_exports_type, /* 169 */ - scheme_logger_type, /* 170 */ - scheme_log_reader_type, /* 171 */ - scheme_marshal_share_type, /* 172 */ - scheme_rib_delimiter_type, /* 173 */ - scheme_noninline_proc_type, /* 174 */ - scheme_prune_context_type, /* 175 */ - scheme_future_type, /* 176 */ - scheme_flvector_type, /* 177 */ - scheme_extflvector_type, /* 178 */ - scheme_fxvector_type, /* 179 */ - scheme_place_type, /* 180 */ - scheme_place_object_type, /* 181 */ - scheme_place_async_channel_type, /* 182 */ - scheme_place_bi_channel_type, /* 183 */ - scheme_once_used_type, /* 184 */ - scheme_serialized_symbol_type, /* 185 */ - scheme_serialized_keyword_type, /* 186 */ - scheme_serialized_structure_type, /* 187 */ - scheme_fsemaphore_type, /* 188 */ - scheme_serialized_tcp_fd_type, /* 189 */ - scheme_serialized_file_fd_type, /* 190 */ - scheme_port_closed_evt_type, /* 191 */ - scheme_proc_shape_type, /* 192 */ - scheme_struct_proc_shape_type, /* 193 */ - scheme_phantom_bytes_type, /* 194 */ - scheme_environment_variables_type, /* 195 */ - scheme_filesystem_change_evt_type, /* 196 */ - scheme_ctype_type, /* 197 */ - scheme_plumber_type, /* 198 */ - scheme_plumber_handle_type, /* 199 */ + scheme_long_double_type, /* 57 */ + scheme_char_string_type, /* 58 */ + scheme_byte_string_type, /* 59 */ + scheme_unix_path_type, /* 60 */ + scheme_windows_path_type, /* 61 */ + scheme_symbol_type, /* 62 */ + scheme_keyword_type, /* 63 */ + scheme_null_type, /* 64 */ + scheme_pair_type, /* 65 */ + scheme_mutable_pair_type, /* 66 */ + scheme_vector_type, /* 67 */ + scheme_inspector_type, /* 68 */ + scheme_input_port_type, /* 69 */ + scheme_output_port_type, /* 70 */ + scheme_eof_type, /* 71 */ + scheme_true_type, /* 72 */ + scheme_false_type, /* 73 */ + scheme_void_type, /* 74 */ + scheme_syntax_compiler_type, /* 75 */ + scheme_macro_type, /* 76 */ + scheme_box_type, /* 77 */ + scheme_thread_type, /* 78 */ + scheme_scope_type, /* 79 */ + scheme_stx_offset_type, /* 80 */ + scheme_cont_mark_set_type, /* 81 */ + scheme_sema_type, /* 82 */ + scheme_hash_table_type, /* 83 */ + scheme_hash_tree_type, /* 84 */ + scheme_eq_hash_tree_type, /* 85 */ + scheme_eqv_hash_tree_type, /* 86 */ + scheme_hash_tree_subtree_type, /* 87 */ + scheme_hash_tree_collision_type, /* 88 */ + scheme_hash_tree_indirection_type, /* 89 */ + scheme_cpointer_type, /* 90 */ + scheme_prefix_type, /* 91 */ + scheme_weak_box_type, /* 92 */ + scheme_ephemeron_type, /* 93 */ + scheme_struct_type_type, /* 94 */ + scheme_module_index_type, /* 95 */ + scheme_set_macro_type, /* 96 */ + scheme_listener_type, /* 97 */ + scheme_namespace_type, /* 98 */ + scheme_config_type, /* 99 */ + scheme_stx_type, /* 100 */ + scheme_will_executor_type, /* 101 */ + scheme_custodian_type, /* 102 */ + scheme_random_state_type, /* 103 */ + scheme_regexp_type, /* 104 */ + scheme_bucket_type, /* 105 */ + scheme_bucket_table_type, /* 106 */ + scheme_subprocess_type, /* 107 */ + scheme_compilation_top_type, /* 108 */ + scheme_wrap_chunk_type, /* 109 */ + scheme_eval_waiting_type, /* 110 */ + scheme_tail_call_waiting_type, /* 111 */ + scheme_undefined_type, /* 112 */ + scheme_struct_property_type, /* 113 */ + scheme_chaperone_property_type, /* 114 */ + scheme_multiple_values_type, /* 115 */ + scheme_placeholder_type, /* 116 */ + scheme_table_placeholder_type, /* 117 */ + scheme_scope_table_type, /* 118 */ + scheme_propagate_table_type, /* 119 */ + scheme_svector_type, /* 120 */ + scheme_resolve_prefix_type, /* 121 */ + scheme_security_guard_type, /* 122 */ + scheme_indent_type, /* 123 */ + scheme_udp_type, /* 124 */ + scheme_udp_evt_type, /* 125 */ + scheme_tcp_accept_evt_type, /* 126 */ + scheme_id_macro_type, /* 127 */ + scheme_evt_set_type, /* 128 */ + scheme_wrap_evt_type, /* 129 */ + scheme_handle_evt_type, /* 130 */ + scheme_replace_evt_type, /* 131 */ + scheme_active_replace_evt_type, /* 132 */ + scheme_nack_guard_evt_type, /* 133 */ + scheme_semaphore_repost_type, /* 134 */ + scheme_channel_type, /* 135 */ + scheme_channel_put_type, /* 136 */ + scheme_thread_resume_type, /* 137 */ + scheme_thread_suspend_type, /* 138 */ + scheme_thread_dead_type, /* 139 */ + scheme_poll_evt_type, /* 140 */ + scheme_nack_evt_type, /* 141 */ + scheme_module_registry_type, /* 142 */ + scheme_thread_set_type, /* 143 */ + scheme_string_converter_type, /* 144 */ + scheme_alarm_type, /* 145 */ + scheme_thread_recv_evt_type, /* 146 */ + scheme_thread_cell_type, /* 147 */ + scheme_channel_syncer_type, /* 148 */ + scheme_special_comment_type, /* 149 */ + scheme_write_evt_type, /* 150 */ + scheme_always_evt_type, /* 151 */ + scheme_never_evt_type, /* 152 */ + scheme_progress_evt_type, /* 153 */ + scheme_place_dead_type, /* 154 */ + scheme_already_comp_type, /* 155 */ + scheme_readtable_type, /* 156 */ + scheme_intdef_context_type, /* 157 */ + scheme_lexical_rib_type, /* 158 */ + scheme_thread_cell_values_type, /* 159 */ + scheme_global_ref_type, /* 160 */ + scheme_cont_mark_chain_type, /* 161 */ + scheme_raw_pair_type, /* 162 */ + scheme_prompt_type, /* 163 */ + scheme_prompt_tag_type, /* 164 */ + scheme_continuation_mark_key_type, /* 165 */ + scheme_expanded_syntax_type, /* 166 */ + scheme_delay_syntax_type, /* 167 */ + scheme_cust_box_type, /* 168 */ + scheme_resolved_module_path_type, /* 169 */ + scheme_module_phase_exports_type, /* 170 */ + scheme_logger_type, /* 171 */ + scheme_log_reader_type, /* 172 */ + scheme_marshal_share_type, /* 173 */ + scheme_rib_delimiter_type, /* 174 */ + scheme_noninline_proc_type, /* 175 */ + scheme_prune_context_type, /* 176 */ + scheme_future_type, /* 177 */ + scheme_flvector_type, /* 178 */ + scheme_extflvector_type, /* 179 */ + scheme_fxvector_type, /* 180 */ + scheme_place_type, /* 181 */ + scheme_place_object_type, /* 182 */ + scheme_place_async_channel_type, /* 183 */ + scheme_place_bi_channel_type, /* 184 */ + scheme_once_used_type, /* 185 */ + scheme_serialized_symbol_type, /* 186 */ + scheme_serialized_keyword_type, /* 187 */ + scheme_serialized_structure_type, /* 188 */ + scheme_fsemaphore_type, /* 189 */ + scheme_serialized_tcp_fd_type, /* 190 */ + scheme_serialized_file_fd_type, /* 191 */ + scheme_port_closed_evt_type, /* 192 */ + scheme_proc_shape_type, /* 193 */ + scheme_struct_proc_shape_type, /* 194 */ + scheme_phantom_bytes_type, /* 195 */ + scheme_environment_variables_type, /* 196 */ + scheme_filesystem_change_evt_type, /* 197 */ + scheme_ctype_type, /* 198 */ + scheme_plumber_type, /* 199 */ + scheme_plumber_handle_type, /* 200 */ #ifdef MZTAG_REQUIRED - _scheme_last_normal_type_, /* 200 */ + _scheme_last_normal_type_, /* 201 */ - scheme_rt_weak_array, /* 201 */ + scheme_rt_weak_array, /* 202 */ - scheme_rt_comp_env, /* 202 */ - scheme_rt_constant_binding, /* 203 */ - scheme_rt_resolve_info, /* 204 */ - scheme_rt_unresolve_info, /* 205 */ - scheme_rt_optimize_info, /* 206 */ - scheme_rt_compile_info, /* 207 */ - scheme_rt_cont_mark, /* 208 */ - scheme_rt_saved_stack, /* 209 */ - scheme_rt_reply_item, /* 210 */ - scheme_rt_closure_info, /* 211 */ - scheme_rt_overflow, /* 212 */ - scheme_rt_overflow_jmp, /* 213 */ - scheme_rt_meta_cont, /* 214 */ - scheme_rt_dyn_wind_cell, /* 215 */ - scheme_rt_dyn_wind_info, /* 216 */ - scheme_rt_dyn_wind, /* 217 */ - scheme_rt_dup_check, /* 218 */ - scheme_rt_thread_memory, /* 219 */ - scheme_rt_input_file, /* 220 */ - scheme_rt_input_fd, /* 221 */ - scheme_rt_oskit_console_input, /* 222 */ - scheme_rt_tested_input_file, /* 223 */ - scheme_rt_tested_output_file, /* 224 */ - scheme_rt_indexed_string, /* 225 */ - scheme_rt_output_file, /* 226 */ - scheme_rt_load_handler_data, /* 227 */ - scheme_rt_pipe, /* 228 */ - scheme_rt_beos_process, /* 229 */ - scheme_rt_system_child, /* 230 */ - scheme_rt_tcp, /* 231 */ - scheme_rt_write_data, /* 232 */ - scheme_rt_tcp_select_info, /* 233 */ - scheme_rt_param_data, /* 234 */ - scheme_rt_will, /* 235 */ - scheme_rt_linker_name, /* 236 */ - scheme_rt_param_map, /* 237 */ - scheme_rt_finalization, /* 238 */ - scheme_rt_finalizations, /* 239 */ - scheme_rt_cpp_object, /* 240 */ - scheme_rt_cpp_array_object, /* 241 */ - scheme_rt_stack_object, /* 242 */ - scheme_rt_preallocated_object, /* 243 */ - scheme_thread_hop_type, /* 244 */ - scheme_rt_srcloc, /* 245 */ - scheme_rt_evt, /* 246 */ - scheme_rt_syncing, /* 247 */ - scheme_rt_comp_prefix, /* 248 */ - scheme_rt_user_input, /* 249 */ - scheme_rt_user_output, /* 250 */ - scheme_rt_compact_port, /* 251 */ - scheme_rt_read_special_dw, /* 252 */ - scheme_rt_regwork, /* 253 */ - scheme_rt_rx_lazy_string, /* 254 */ - scheme_rt_buf_holder, /* 255 */ - scheme_rt_parameterization, /* 256 */ - scheme_rt_print_params, /* 257 */ - scheme_rt_read_params, /* 258 */ - scheme_rt_native_code, /* 259 */ - scheme_rt_native_code_plus_case, /* 260 */ - scheme_rt_jitter_data, /* 261 */ - scheme_rt_module_exports, /* 262 */ - scheme_rt_delay_load_info, /* 263 */ - scheme_rt_marshal_info, /* 264 */ - scheme_rt_unmarshal_info, /* 265 */ - scheme_rt_runstack, /* 266 */ - scheme_rt_sfs_info, /* 267 */ - scheme_rt_validate_clearing, /* 268 */ - scheme_rt_lightweight_cont, /* 269 */ - scheme_rt_export_info, /* 270 */ - scheme_rt_cont_jmp, /* 271 */ - scheme_rt_letrec_check_frame, /* 272 */ + scheme_rt_comp_env, /* 203 */ + scheme_rt_constant_binding, /* 204 */ + scheme_rt_resolve_info, /* 205 */ + scheme_rt_unresolve_info, /* 206 */ + scheme_rt_optimize_info, /* 207 */ + scheme_rt_compile_info, /* 208 */ + scheme_rt_cont_mark, /* 209 */ + scheme_rt_saved_stack, /* 210 */ + scheme_rt_reply_item, /* 211 */ + scheme_rt_closure_info, /* 212 */ + scheme_rt_overflow, /* 213 */ + scheme_rt_overflow_jmp, /* 214 */ + scheme_rt_meta_cont, /* 215 */ + scheme_rt_dyn_wind_cell, /* 216 */ + scheme_rt_dyn_wind_info, /* 217 */ + scheme_rt_dyn_wind, /* 218 */ + scheme_rt_dup_check, /* 219 */ + scheme_rt_thread_memory, /* 220 */ + scheme_rt_input_file, /* 221 */ + scheme_rt_input_fd, /* 222 */ + scheme_rt_oskit_console_input, /* 223 */ + scheme_rt_tested_input_file, /* 224 */ + scheme_rt_tested_output_file, /* 225 */ + scheme_rt_indexed_string, /* 226 */ + scheme_rt_output_file, /* 227 */ + scheme_rt_load_handler_data, /* 228 */ + scheme_rt_pipe, /* 229 */ + scheme_rt_beos_process, /* 230 */ + scheme_rt_system_child, /* 231 */ + scheme_rt_tcp, /* 232 */ + scheme_rt_write_data, /* 233 */ + scheme_rt_tcp_select_info, /* 234 */ + scheme_rt_param_data, /* 235 */ + scheme_rt_will, /* 236 */ + scheme_rt_linker_name, /* 237 */ + scheme_rt_param_map, /* 238 */ + scheme_rt_finalization, /* 239 */ + scheme_rt_finalizations, /* 240 */ + scheme_rt_cpp_object, /* 241 */ + scheme_rt_cpp_array_object, /* 242 */ + scheme_rt_stack_object, /* 243 */ + scheme_rt_preallocated_object, /* 244 */ + scheme_thread_hop_type, /* 245 */ + scheme_rt_srcloc, /* 246 */ + scheme_rt_evt, /* 247 */ + scheme_rt_syncing, /* 248 */ + scheme_rt_comp_prefix, /* 249 */ + scheme_rt_user_input, /* 250 */ + scheme_rt_user_output, /* 251 */ + scheme_rt_compact_port, /* 252 */ + scheme_rt_read_special_dw, /* 253 */ + scheme_rt_regwork, /* 254 */ + scheme_rt_rx_lazy_string, /* 255 */ + scheme_rt_buf_holder, /* 256 */ + scheme_rt_parameterization, /* 257 */ + scheme_rt_print_params, /* 258 */ + scheme_rt_read_params, /* 259 */ + scheme_rt_native_code, /* 260 */ + scheme_rt_native_code_plus_case, /* 261 */ + scheme_rt_jitter_data, /* 262 */ + scheme_rt_module_exports, /* 263 */ + scheme_rt_delay_load_info, /* 264 */ + scheme_rt_marshal_info, /* 265 */ + scheme_rt_unmarshal_info, /* 266 */ + scheme_rt_runstack, /* 267 */ + scheme_rt_sfs_info, /* 268 */ + scheme_rt_validate_clearing, /* 269 */ + scheme_rt_lightweight_cont, /* 270 */ + scheme_rt_export_info, /* 271 */ + scheme_rt_cont_jmp, /* 272 */ + scheme_rt_letrec_check_frame, /* 273 */ #endif - scheme_deferred_expr_type, /* 273 */ + scheme_deferred_expr_type, /* 274 */ _scheme_last_type_ }; diff --git a/racket/src/racket/src/type.c b/racket/src/racket/src/type.c index a131b57ac6..61332e1069 100644 --- a/racket/src/racket/src/type.c +++ b/racket/src/racket/src/type.c @@ -135,6 +135,7 @@ scheme_init_type () set_name(scheme_require_form_type, ""); set_name(scheme_varref_form_type, ""); set_name(scheme_apply_values_type, ""); + set_name(scheme_with_immed_mark_type, ""); set_name(scheme_case_lambda_sequence_type, ""); set_name(scheme_let_value_type, ""); @@ -574,6 +575,7 @@ void scheme_register_traversers(void) GC_REG_TRAV(scheme_begin_for_syntax_type, vector_obj); GC_REG_TRAV(scheme_varref_form_type, twoptr_obj); GC_REG_TRAV(scheme_apply_values_type, twoptr_obj); + GC_REG_TRAV(scheme_with_immed_mark_type, with_cont_mark); GC_REG_TRAV(scheme_boxenv_type, twoptr_obj); GC_REG_TRAV(scheme_case_lambda_sequence_type, case_closure); GC_REG_TRAV(scheme_begin0_sequence_type, seq_rec); diff --git a/racket/src/racket/src/validate.c b/racket/src/racket/src/validate.c index 8959163593..d9c9ec7211 100644 --- a/racket/src/racket/src/validate.c +++ b/racket/src/racket/src/validate.c @@ -1995,6 +1995,36 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr, result_ignored, vc, tailpos, procs); result = validate_join(0, result); break; + case scheme_with_immed_mark_type: + { + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)expr; + int r; + + no_typed(need_local_type, port); + + r = validate_expr(port, wcm->key, stack, tls, depth, letlimit, delta, + num_toplevels, num_stxes, num_lifts, tl_use_map, + tl_state, tl_timestamp, + NULL, 0, 0, vc, 0, 0, procs, + 1, _st_ht); + result = validate_join_seq(r, result); + + r = validate_expr(port, wcm->val, stack, tls, depth, letlimit, delta, + num_toplevels, num_stxes, num_lifts, tl_use_map, + tl_state, tl_timestamp, + NULL, 0, 0, vc, 0, 0, procs, + 1, _st_ht); + result = validate_join_seq(r, result); + + --delta; + if (delta < 0) + scheme_ill_formed_code(port); + stack[delta] = VALID_VAL; + + expr = wcm->body; + goto top; + } + break; case scheme_case_lambda_sequence_type: no_typed(need_local_type, port); case_lambda_validate(expr, port, stack, tls, depth, letlimit, delta, From 27fed2b1ed7a1d028e6af937a1753c674346e866 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 5 Aug 2015 17:57:51 -0600 Subject: [PATCH 004/381] document `compiler/zo-struct` changes for new bytecode form --- pkgs/racket-doc/scribblings/raco/decompile.scrbl | 5 ++++- pkgs/racket-doc/scribblings/raco/zo-struct.scrbl | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/raco/decompile.scrbl b/pkgs/racket-doc/scribblings/raco/decompile.scrbl index 2a680ba996..8cb9d9c4e1 100644 --- a/pkgs/racket-doc/scribblings/raco/decompile.scrbl +++ b/pkgs/racket-doc/scribblings/raco/decompile.scrbl @@ -104,7 +104,10 @@ Many forms in the decompiled code, such as @racket[module], @item{A form @racket[(#%apply-values _proc _expr)] is equivalent to @racket[(call-with-values (lambda () _expr) _proc)], but the run-time - system avoids allocating a closure for @racket[_expr].} + system avoids allocating a closure for @racket[_expr]. Similarly, + a @racket[#%call-with-immediate-continuation-mark] call is equivalent to + a @racket[call-with-immediate-continuation-mark] call, but avoiding + a closure allocation.} @item{A @racket[define-values] form may have @racket[(begin '%%inline-variant%% _expr1 _expr2)] for its expression, in which case diff --git a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl index 371e067f15..c2be857a63 100644 --- a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl +++ b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl @@ -567,6 +567,22 @@ binding, constructor, etc.} which is handled specially by the run-time system.} +@defstruct+[(with-immed-mark expr) + ([key (or/c expr? seq? any/c)] + [val (or/c expr? seq? any/c)] + [body (or/c expr? seq? any/c)])]{ + + Represents a @racket[(call-with-immediate-continuation-mark key + (lambda (_arg) _body) val)] expression that is handled specially by + the run-time system to avoid a closure allocation. One initialized + slot is pushed onto the stack after @racket[expr] and @racket[val] + are evaluated and before @racket[body] is evaluated. + + After each of @racket[key] and @racket[val] is evaluated, the stack is + restored to its depth from before evaluating @racket[key] or + @racket[val].} + + @defstruct+[(primval expr) ([id exact-nonnegative-integer?])]{ Represents a direct reference to a variable imported from the run-time From 6bcb449b55deca1b28b3f1d7e91e8052849b1026 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 5 Aug 2015 12:03:29 -0600 Subject: [PATCH 005/381] fix `impersonator-property:application-mark` propagation Propagate the mark value only if it's on the current continuation frame, as originally intended. Adjust the docs to clarify. --- .../scribblings/reference/chaperones.scrbl | 8 ++++--- .../tests/racket/chaperone.rktl | 21 +++++++++++++++++++ racket/src/racket/src/fun.c | 2 +- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl index 21cee89b8a..747835735c 100644 --- a/pkgs/racket-doc/scribblings/reference/chaperones.scrbl +++ b/pkgs/racket-doc/scribblings/reference/chaperones.scrbl @@ -221,9 +221,11 @@ If any @racket[prop] is @racket[impersonator-prop:application-mark] and if the associated @racket[prop-val] is a pair, then the call to @racket[proc] is wrapped with @racket[with-continuation-mark] using @racket[(car prop-val)] as the mark key and @racket[(cdr prop-val)] as the mark -value. In addition, if @racket[continuation-mark-set-first] with -@racket[(car prop-val)] produces a value for the immediate -continuation frame of the call to the impersonated procedure, the value is +value. In addition, if the immediate +continuation frame of the call to the impersonated procedure +includes a value for @racket[(car prop-val)]---that is, if +@racket[call-with-immediate-continuation-mark] would produce a value +for @racket[(car prop-val)] in the call's continuation---then the value is also installed as an immediate value for @racket[(car prop-val)] as a mark during the call to @racket[wrapper-proc] (which allows tail-calls of impersonators with respect to wrapping impersonators to be detected within diff --git a/pkgs/racket-test-core/tests/racket/chaperone.rktl b/pkgs/racket-test-core/tests/racket/chaperone.rktl index b44fa58a5b..482e62d849 100644 --- a/pkgs/racket-test-core/tests/racket/chaperone.rktl +++ b/pkgs/racket-test-core/tests/racket/chaperone.rktl @@ -1883,6 +1883,27 @@ (f 42)) (test '(#f #f) values msgs)) +;; Make sure that `impersonator-prop:application-mark' +;; doesn't propagate for non-tail values: +(let () + (define msgs '()) + (define (wrap f) + (chaperone-procedure + f + (λ (x) + (call-with-immediate-continuation-mark + 'key + (λ (m) + (set! msgs (cons m msgs)) + (values x)))) + impersonator-prop:application-mark + (cons 'key 'skip-this-check))) + + (test 42 + values + ((wrap (lambda (x) (+ ((wrap (lambda (x) x)) x) 0))) 42)) + (test '(#f #f) values msgs)) + ;; ---------------------------------------- ;; Check that supplying a procedure `to make-keyword-procedure' that diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 5c727d4af2..a1f0002fe0 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -3691,7 +3691,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object app_mark = NULL; if (app_mark) { - v = scheme_extract_one_cc_mark(NULL, SCHEME_CAR(app_mark)); + v = scheme_chaperone_get_immediate_cc_mark(SCHEME_CAR(app_mark), NULL); if (v) { scheme_push_continuation_frame(&cframe); scheme_set_cont_mark(SCHEME_CAR(app_mark), v); From 0efd05221832f6c0875416bc578e24f9c8a1f1b8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 6 Aug 2015 09:24:47 -0600 Subject: [PATCH 006/381] fix single-float hashing --- racket/src/racket/src/hash.c | 8 +++++++- racket/src/racket/src/print.c | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index c63dfd21ea..2a846d72bb 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -1204,6 +1204,9 @@ XFORM_NONGCING static uintptr_t fast_equal_hash_key(Scheme_Object *o, uintptr_t } #ifdef MZ_USE_SINGLE_FLOATS case scheme_float_type: + { + return k + dbl_hash_val(SCHEME_FLT_VAL(o)); + } #endif case scheme_double_type: { @@ -1727,10 +1730,13 @@ XFORM_NONGCING static uintptr_t fast_equal_hash_key2(Scheme_Object *o, int *_don return t - SCHEME_INT_VAL(o); #ifdef MZ_USE_SINGLE_FLOATS case scheme_float_type: + { + return dbl_hash2_val(SCHEME_FLT_VAL(o)); + } #endif case scheme_double_type: { - return dbl_hash2_val(SCHEME_FLOAT_VAL(o)); + return dbl_hash2_val(SCHEME_DBL_VAL(o)); } #ifdef MZ_LONG_DOUBLE case scheme_long_double_type: diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index 002f9412ab..bf89561d01 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -1446,6 +1446,7 @@ static int compare_keys(const void *a, const void *b) || SCHEME_CHAR_STRINGP(v) \ || SCHEME_BYTE_STRINGP(v) \ || SCHEME_CHARP(v) \ + || SCHEME_NUMBERP(v) \ || SAME_TYPE(SCHEME_TYPE(v), scheme_module_index_type)) av = ((Scheme_Object **)a)[0]; bv = ((Scheme_Object **)b)[0]; From a55eed9718e1fc2183676f8507807b485329d06d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 7 Aug 2015 05:25:42 -0600 Subject: [PATCH 007/381] fix `data/integer-set` for 32-bit platforms --- racket/collects/data/private/count-bits-in-fixnum.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/racket/collects/data/private/count-bits-in-fixnum.rkt b/racket/collects/data/private/count-bits-in-fixnum.rkt index f9b7deb38e..b064ed11af 100644 --- a/racket/collects/data/private/count-bits-in-fixnum.rkt +++ b/racket/collects/data/private/count-bits-in-fixnum.rkt @@ -38,7 +38,10 @@ [(_ expr bits0) ;; Choose at compile time what word length is (let* ([bits (syntax-e #'bits0)] - [bits (or bits (if (fixnum? (expt 2 61)) 62 30))] + [bits (or bits + ;; for portable bytecode, use a fixnum size tha + ;; always works: + 30)] [lut (cond [(<= bits 8) lut8] [(<= bits 30) lut30] From 2661d4692997f1c7ec9c0d650733eee6ecdf9fdd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 5 Aug 2015 16:25:08 -0600 Subject: [PATCH 008/381] toward deterministic bytecode generation Progress toward making the bytecode compiler deterministic, so that a fresh `make base` always produces exactly the same bytecode from the same sources. Most changes involve avoiding hash-table order dependencies and adjusting scope identity. The namespace used to load a reader extension is also better defined. Plus many other little changes. The identity of a scope that is unmarshaled from a bytecode file now incorporates the hash of the file, and the relative order of scopes is preserved in a bytecode file. This combination allows compilation to start with modules that loaded and compiled in different orders (including delayed loading of bytecode fragments within one file). Formerly, a reader extension triggered by `#lang` or `#reader` was loaded in whatever namespace happens to be current. That's unpredictable and can pollute a module build at the level of bytecode. To help make builds deterministic, reader extensions are now loaded in a root namespace of the current namespace. Deterministic compilation in general relies on deterministic macros. The two most common ways for a macro to be non-deterministic are by using `gensym` (use `generate-temporaries`, instead) and by using an unsorted hash-table traversal (don't do that). At this point, bytecode generation is unlikely to be completely deterministic, since I uncovered non-determinism mostly by iterating attempts over the base collections. For now, the intent is not to provide guarantees outside of the compilation of the base collections --- but "more deterministic" is likely to be useful in the short run, and we can improve further in the long run. --- pkgs/base/info.rkt | 2 +- pkgs/racket-doc/scribblings/raco/make.scrbl | 12 + .../scribblings/reference/hashes.scrbl | 25 +- .../scribblings/reference/namespaces.scrbl | 18 +- .../scribblings/reference/read.scrbl | 4 +- .../scribblings/reference/reader.scrbl | 3 +- pkgs/racket-test-core/tests/racket/basic.rktl | 4 +- .../tests/racket/deterministic-zo.rkt | 68 + racket/collects/compiler/cm.rkt | 13 +- .../contract/private/arrow-higher-order.rkt | 9 +- .../racket/contract/private/arrow.rkt | 6 +- .../racket/contract/private/helpers.rkt | 8 +- racket/collects/racket/match/compiler.rkt | 24 +- racket/collects/racket/match/patterns.rkt | 9 +- .../collects/racket/private/define-et-al.rkt | 2 +- .../collects/racket/private/more-scheme.rkt | 2 +- racket/collects/racket/private/pre-base.rkt | 6 +- racket/collects/racket/private/qq-and-or.rkt | 2 +- racket/collects/racket/private/sc.rkt | 7 +- racket/collects/setup/main.rkt | 2 +- .../syntax/parse/experimental/dset.rkt | 54 + .../syntax/parse/experimental/template.rkt | 52 +- .../syntax/parse/private/rep-attrs.rkt | 5 +- racket/src/racket/gc2/check-sdep.rkt | 2 +- racket/src/racket/gc2/xform.rkt | 2 +- racket/src/racket/src/bool.c | 22 +- racket/src/racket/src/compenv.c | 2 +- racket/src/racket/src/cstartup.inc | 3054 ++++++++--------- racket/src/racket/src/env.c | 5 + racket/src/racket/src/fun.c | 2 - racket/src/racket/src/list.c | 46 +- racket/src/racket/src/marshal.c | 66 +- racket/src/racket/src/module.c | 8 +- racket/src/racket/src/mzmark_print.inc | 2 + racket/src/racket/src/mzmark_type.inc | 2 + racket/src/racket/src/mzmarksrc.c | 2 + racket/src/racket/src/number.c | 2 +- racket/src/racket/src/print.c | 106 +- racket/src/racket/src/read.c | 103 +- racket/src/racket/src/schminc.h | 4 +- racket/src/racket/src/schpriv.h | 8 +- racket/src/racket/src/schvers.h | 4 +- racket/src/racket/src/startup.inc | 2 +- racket/src/racket/src/startup.rktl | 3 +- racket/src/racket/src/syntax.c | 452 ++- 45 files changed, 2476 insertions(+), 1760 deletions(-) create mode 100644 pkgs/racket-test/tests/racket/deterministic-zo.rkt create mode 100644 racket/collects/syntax/parse/experimental/dset.rkt diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 95afdfd40f..925cde7806 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.6") +(define version "6.2.900.8") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/raco/make.scrbl b/pkgs/racket-doc/scribblings/raco/make.scrbl index 4407484024..4e5d4af085 100644 --- a/pkgs/racket-doc/scribblings/raco/make.scrbl +++ b/pkgs/racket-doc/scribblings/raco/make.scrbl @@ -497,6 +497,18 @@ result will not call @racket[proc] with @racket['unlock].) compilations of the same racket source files in multiple places. } +@defproc[(install-module-hashes! [bstr btyes?] + [start exact-nonnegatve-integer? 0] + [end exact-nonnegatve-integer? (bytes-length bstr)]) + void?]{ + +Adjusts the bytecode representation in @racket[bstr] (from bytes +@racket[start] to @racket[end]) to install a hash code, including any +submodules within the region. The existing representation should have +zero bytes in place of each hash string, which is what @racket[write] +produces for a compiled form. + +@history[#:added "6.2.900.8"]} @; ---------------------------------------------------------------------- diff --git a/pkgs/racket-doc/scribblings/reference/hashes.scrbl b/pkgs/racket-doc/scribblings/reference/hashes.scrbl index 576242727c..bd41fff249 100644 --- a/pkgs/racket-doc/scribblings/reference/hashes.scrbl +++ b/pkgs/racket-doc/scribblings/reference/hashes.scrbl @@ -355,13 +355,15 @@ procedure and mutability of @racket[hash].} @defproc[(hash-map [hash hash?] - [proc (any/c any/c . -> . any/c)]) + [proc (any/c any/c . -> . any/c)] + [try-order? any/c #f]) (listof any/c)]{ Applies the procedure @racket[proc] to each element in @racket[hash] in an unspecified order, accumulating the results into a list. The procedure @racket[proc] is called each time with a -key and its value. +key and its value, and the procedure's individual results appear in +order in the result list. If a hash table is extended with new keys (either through @racket[proc] or by another thread) while a @racket[hash-map] or @@ -372,7 +374,14 @@ change does not affect a traversal if the key has been seen already, otherwise the traversal skips a deleted key or uses the remapped key's new value. -@see-also-concurrency-caveat[]} +If @racket[try-order?] is true, then the order of keys and values +passed to @racket[proc] is normalized under certain circumstances, +such as when the keys are all symbols and @racket[hash] is not an +@tech{impersonator}. + +@see-also-concurrency-caveat[] + +@history[#:changed "6.2.900.8" @elem{Added the @racket[try-order?] argument.}]} @defproc[(hash-keys [hash hash?]) (listof any/c)]{ @@ -396,15 +405,19 @@ See @racket[hash-map] for information about modifying @racket[hash] during @racket[hash->list]. @see-also-concurrency-caveat[]} @defproc[(hash-for-each [hash hash?] - [proc (any/c any/c . -> . any)]) + [proc (any/c any/c . -> . any)] + [try-order? any/c #f]) void?]{ Applies @racket[proc] to each element in @racket[hash] (for the side-effects of @racket[proc]) in an unspecified order. The procedure @racket[proc] is called each time with a key and its value. -See @racket[hash-map] for information about modifying @racket[hash] -within @racket[proc]. @see-also-concurrency-caveat[]} +See @racket[hash-map] for information about @racket[try-order?] and +about modifying @racket[hash] within @racket[proc]. +@see-also-concurrency-caveat[] + +@history[#:changed "6.2.900.8" @elem{Added the @racket[try-order?] argument.}]} @defproc[(hash-count [hash hash?]) diff --git a/pkgs/racket-doc/scribblings/reference/namespaces.scrbl b/pkgs/racket-doc/scribblings/reference/namespaces.scrbl index ecc8b4e560..83f1e67f0d 100644 --- a/pkgs/racket-doc/scribblings/reference/namespaces.scrbl +++ b/pkgs/racket-doc/scribblings/reference/namespaces.scrbl @@ -21,16 +21,22 @@ otherwise.} @defproc[(make-empty-namespace) namespace?]{ -Creates a new namespace that is empty, and whose @tech{module +Creates a new @tech{namespace} that is empty, and whose @tech{module registry} contains no mappings. The namespace's @tech{base phase} is the same as the @tech{base phase} of the @tech{current namespace}. Attach modules from an existing namespace to the new one -with @racket[namespace-attach-module].} +with @racket[namespace-attach-module]. + +The new namespace is associated with a new @deftech{root namespace}, +which has the same @tech{module registry} as the returned namespace +and has a @tech{base phase} of 0. The new @tech{root namespace} is +the same as the returned namespace if both have @tech{base phase} 0.} @defproc[(make-base-empty-namespace) namespace?]{ -Creates a new empty namespace, but with @racketmodname[racket/base] +Creates a new empty @tech{namespace} like @racket[make-empty-namespace], +but with @racketmodname[racket/base] attached. The namespace's @tech{base phase} is the same as the @tech{phase} in which the @racket[make-base-empty-namespace] function was created.} @@ -38,7 +44,8 @@ function was created.} @defproc[(make-base-namespace) namespace?]{ -Creates a new namespace with @racketmodname[racket/base] attached and +Creates a new @tech{namespace} like @racket[make-empty-namespace], but +with @racketmodname[racket/base] attached and @racket[require]d into the top-level environment. The namespace's @tech{base phase} is the same as the @tech{phase} in which the @racket[make-base-namespace] function was created.} @@ -62,7 +69,8 @@ Returns @racket[#t] if @racket[v] is a namespace-anchor value, @defproc[(namespace-anchor->empty-namespace [a namespace-anchor?]) namespace?]{ -Returns an empty namespace that shares a @tech{module registry} with +Returns an empty namespace that shares a @tech{module registry} +and @tech{root namespace} with the source of the anchor, and whose @tech{base phase} is the @tech{phase} in which the anchor was created. diff --git a/pkgs/racket-doc/scribblings/reference/read.scrbl b/pkgs/racket-doc/scribblings/reference/read.scrbl index f1cc3b1f90..635187e1aa 100644 --- a/pkgs/racket-doc/scribblings/reference/read.scrbl +++ b/pkgs/racket-doc/scribblings/reference/read.scrbl @@ -121,7 +121,9 @@ See @secref["readtables"] for an extended example that uses (or/c (any/c any/c . -> . any) #f)]{ Reads from @racket[in] in the same way as @racket[read], but stopping as -soon as a @tech{reader language} (or its absence) is determined. +soon as a @tech{reader language} (or its absence) is determined, and +using the @tech{current namespace} to load a reader module instead +of its @tech{root namespace} (if those are different). A @deftech{reader language} is specified by @litchar{#lang} or @litchar{#!} (see @secref["parse-reader"]) at the beginning of the diff --git a/pkgs/racket-doc/scribblings/reference/reader.scrbl b/pkgs/racket-doc/scribblings/reference/reader.scrbl index b30f99a816..f01f408323 100644 --- a/pkgs/racket-doc/scribblings/reference/reader.scrbl +++ b/pkgs/racket-doc/scribblings/reference/reader.scrbl @@ -866,7 +866,8 @@ and passes it to the procedure that is the value of the module path. The module path is passed to @racket[dynamic-require] with either @racket['read] or @racket['read-syntax] (depending on whether the reader is in @racket[read] or @racket[read-syntax] -mode). +mode). The module is loaded in a @tech{root namespace} of the +@tech{current namespace}. The arity of the resulting procedure determines whether it accepts extra source-location information: a @racketidfont{read} procedure diff --git a/pkgs/racket-test-core/tests/racket/basic.rktl b/pkgs/racket-test-core/tests/racket/basic.rktl index c57b19231e..1e49626a45 100644 --- a/pkgs/racket-test-core/tests/racket/basic.rktl +++ b/pkgs/racket-test-core/tests/racket/basic.rktl @@ -2548,8 +2548,8 @@ (arity-test hash-set 3 3) (arity-test hash-remove! 2 2) (arity-test hash-remove 2 2) -(arity-test hash-map 2 2) -(arity-test hash-for-each 2 2) +(arity-test hash-map 2 3) +(arity-test hash-for-each 2 3) (arity-test hash? 1 1) (arity-test hash-eq? 1 1) (arity-test hash-weak? 1 1) diff --git a/pkgs/racket-test/tests/racket/deterministic-zo.rkt b/pkgs/racket-test/tests/racket/deterministic-zo.rkt new file mode 100644 index 0000000000..5b8762aa6b --- /dev/null +++ b/pkgs/racket-test/tests/racket/deterministic-zo.rkt @@ -0,0 +1,68 @@ +#lang racket/base +(require syntax/modread + racket/file + compiler/compilation-path + compiler/cm) + +(define (go dir collects-dir fn) + (parameterize ([current-load-relative-directory dir]) + (define path (build-path dir fn)) + (define stx + (check-module-form + (call-with-input-file* + path + (lambda (i) + (port-count-lines! i) + (with-module-reading-parameterization + (lambda () + (read-syntax path i))))) + 'mod + #f)) + (define o (open-output-bytes)) + (parameterize ([current-namespace (make-base-namespace)] + [current-write-relative-directory (cons dir collects-dir)]) + (dynamic-require 'racket/private/base #f) + (write (compile stx) o)) + (define bstr (get-output-bytes o)) + (install-module-hashes! bstr) + bstr)) + +(define (check-file dir collects-dir sub-dir f) + (printf "~a\n" (build-path sub-dir f)) + (define c1 (go dir collects-dir f)) + (define c2 (go dir collects-dir f)) + (unless (equal? c1 c2) + (call-with-output-file* "/tmp/c1" #:exists 'truncate (lambda (o) (write-bytes c1 o))) + (call-with-output-file* "/tmp/c2" #:exists 'truncate (lambda (o) (write-bytes c2 o))) + (error "failed")) + (define zo (get-compilation-bytecode-file (build-path dir f) #:modes '("compiled"))) + (when (file-exists? zo) + (define c3 (file->bytes zo)) + (unless (equal? c3 c1) + (call-with-output-file* "/tmp/c1" #:exists 'truncate (lambda (o) (write-bytes c1 o))) + (call-with-output-file* "/tmp/c2" #:exists 'truncate (lambda (o) (write-bytes c3 o))) + (error "failed relative to built")))) + +(define (check dir [collects-dir dir] [sub-dir 'same] #:limit [limit +inf.0]) + (for/fold ([limit limit]) ([f (in-list (directory-list dir))] + #:when (positive? limit)) + (cond + [(and (regexp-match? #rx"[.]rkt$" f) + (file-exists? (build-path dir f))) + (check-file dir collects-dir sub-dir f) + (sub1 limit)] + [(directory-exists? (build-path dir f)) + (check (build-path dir f) collects-dir (build-path sub-dir f) #:limit limit)] + [else limit]))) + +(define (check-one collects-dir collects file) + (check-file (build-path collects-dir collects) collects-dir collects file)) + +(let-values ([(dir name dir?) + (split-path + (collection-file-path "sc.rkt" "racket/private"))]) + (define collects-dir (simplify-path (build-path dir 'up 'up))) + ;; To check just one: + #; (check-one collects-dir "syntax" "free-vars.rkt") + (check (simplify-path collects-dir)) + (void)) diff --git a/racket/collects/compiler/cm.rkt b/racket/collects/compiler/cm.rkt index b92adca448..6236e761a0 100644 --- a/racket/collects/compiler/cm.rkt +++ b/racket/collects/compiler/cm.rkt @@ -31,7 +31,9 @@ parallel-lock-client make-compile-lock - compile-lock->parallel-lock-client) + compile-lock->parallel-lock-client + + install-module-hashes!) (define cm-logger (make-logger 'compiler/cm (current-logger))) (define (default-manager-trace-handler str) @@ -308,10 +310,13 @@ (write (list* (version) (cons (or src-sha1 (get-source-sha1 path)) (get-dep-sha1s deps up-to-date collection-cache read-src-syntax mode roots #t #hash())) - deps) + (sort deps s-expdate sec)]) (format "~a-~a-~a ~a:~a:~a" @@ -459,7 +464,7 @@ (write code b) ;; Compute SHA1 over modules within bytecode (let* ([s (get-output-bytes b)]) - (install-module-hashes! s 0 (bytes-length s)) + (install-module-hashes! s) ;; Write out the bytecode with module hash (write-bytes s out))))) ;; redundant, but close as early as possible: @@ -471,7 +476,7 @@ external-deps external-module-deps reader-deps up-to-date collection-cache read-src-syntax))))) -(define (install-module-hashes! s start len) +(define (install-module-hashes! s [start 0] [len (bytes-length s)]) (define vlen (bytes-ref s (+ start 2))) (define mode (integer->char (bytes-ref s (+ start 3 vlen)))) (case mode diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index c0994902ee..28e82fc5d6 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -1,6 +1,7 @@ #lang racket/base (require (for-syntax racket/base - "arr-util.rkt") + "arr-util.rkt" + "helpers.rkt") "arity-checking.rkt" "kwd-info-struct.rkt" "blame.rkt" @@ -151,7 +152,7 @@ [(rng-x ...) (if rngs (generate-temporaries rngs) '())]) (with-syntax ([(rng-checker-name ...) (if rngs - (list (gensym 'rng-checker)) + (list (gen-id 'rng-checker)) null)] [(rng-checker ...) (if rngs @@ -274,7 +275,7 @@ (arrow:check-tail-contract #'(rng-ctc ...) #'(rng-checker-name ...) outer-stx-gen))))]) - (with-syntax ([basic-lambda-name (gensym 'basic-lambda)] + (with-syntax ([basic-lambda-name (gen-id 'basic-lambda)] [basic-lambda #'(λ basic-params ;; Arrow contract domain checking is instrumented ;; both here, and in `arity-checking-wrapper'. @@ -290,7 +291,7 @@ (cons blame neg-party) (let () pre ... basic-return)))] - [kwd-lambda-name (gensym 'kwd-lambda)] + [kwd-lambda-name (gen-id 'kwd-lambda)] [kwd-lambda #`(λ kwd-lam-params (with-continuation-mark contract-continuation-mark-key diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index c27630dfff..8f0202189c 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -229,7 +229,7 @@ [(rng-x ...) (if rngs (generate-temporaries rngs) '())]) (with-syntax ([(rng-checker-name ...) (if rngs - (list (gensym 'rng-checker)) + (list (gen-id 'rng-checker)) null)] [(rng-checker ...) (if rngs @@ -322,7 +322,7 @@ #,(if no-rng-checking? (outer-stx-gen #'()) (check-tail-contract #'(rng-ctc ...) #'(rng-checker-name ...) outer-stx-gen))))]) - (with-syntax ([basic-lambda-name (gensym 'basic-lambda)] + (with-syntax ([basic-lambda-name (gen-id 'basic-lambda)] [basic-lambda #'(λ basic-params ;; Arrow contract domain checking is instrumented ;; both here, and in `arity-checking-wrapper'. @@ -337,7 +337,7 @@ contract-continuation-mark-key blame (let () pre ... basic-return)))] - [kwd-lambda-name (gensym 'kwd-lambda)] + [kwd-lambda-name (gen-id 'kwd-lambda)] [kwd-lambda #`(λ kwd-lam-params (with-continuation-mark contract-continuation-mark-key blame diff --git a/racket/collects/racket/contract/private/helpers.rkt b/racket/collects/racket/contract/private/helpers.rkt index 63ff6dc25c..c98706571d 100644 --- a/racket/collects/racket/contract/private/helpers.rkt +++ b/racket/collects/racket/contract/private/helpers.rkt @@ -8,7 +8,8 @@ all-but-last known-good-contract? known-good-contracts - update-loc) + update-loc + gen-id) (require setup/main-collects racket/struct-info @@ -373,5 +374,8 @@ (free-identifier=? id (datum->syntax #'here r-id)))) (define (known-good-contracts) - (for/list ([(k v) (in-hash known-good-syms-ht)]) + (for/list ([k (in-list (sort (hash-keys known-good-syms-ht) symbolsyntax #'here k))) + +(define (gen-id sym) + (car (generate-temporaries (list sym)))) diff --git a/racket/collects/racket/match/compiler.rkt b/racket/collects/racket/match/compiler.rkt index 21ea8e1260..758b20e679 100644 --- a/racket/collects/racket/match/compiler.rkt +++ b/racket/collects/racket/match/compiler.rkt @@ -15,17 +15,27 @@ (define vars-seen (make-parameter null)) (define (hash-on f elems #:equal? [eql #t]) - (define-values (ht ref set!) + (define-values (ht h-ref h-set!) (case eql [(#t) (values (make-hash) hash-ref hash-set!)] [(#f) (values (make-hasheq) hash-ref hash-set!)])) + (define keys null) ;; put all the elements e in the ht, indexed by (f e) (for ([r ;; they need to be in the original order when they come out (reverse elems)]) (define k (f r)) - (set! ht k (cons r (ref ht k (lambda () null))))) - ht) + (h-set! ht k (cons r (h-ref ht k (lambda () + (set! keys (cons k keys)) + null))))) + ;; Return a list, instead of a hash, to make order deterministic + ;; based on the recorded order of keys + (for/list ([k (in-list keys)]) + (cons k (hash-ref ht k)))) + +;; Like `hash-map`, bu for a list produced by `hash-on`: +(define (hash-on-map ht-l f) + (map (lambda (p) (f (car p) (cdr p))) ht-l)) ;; generate a clause of kind k ;; for rows rows, with matched variable x and rest variable xs @@ -74,7 +84,7 @@ (let ([ht (hash-on (lambda (r) (length (Vector-ps (Row-first-pat r)))) rows)]) (with-syntax ([(clauses ...) - (hash-map + (hash-on-map ht (lambda (arity rows) (define ns (build-list arity values)) @@ -123,7 +133,7 @@ [(Exact? first) (let ([ht (hash-on (compose Exact-v Row-first-pat) block #:equal? #t)]) (with-syntax ([(clauses ...) - (hash-map + (hash-on-map ht (lambda (k v) #`[(equal? #,x '#,k) @@ -188,7 +198,7 @@ (let ;; put all the rows in the hash, indexed by their constructor ([ht (hash-on (lambda (r) (pat-key (Row-first-pat r))) block)]) (with-syntax ([(clauses ...) - (hash-map + (hash-on-map ht (lambda (k v) (gen-clause k v x xs esc)))]) #`(cond clauses ... [else (#,esc)])))] ;; the Or rule @@ -298,7 +308,7 @@ ;; we use the pattern so that it can have a custom equal+hash (define ht (hash-on (lambda (r) (Row-first-pat r)) block #:equal? #t)) (with-syntax ([(clauses ...) - (hash-map + (hash-on-map ht (lambda (k v) (gen-clause (Pred-pred k) v x xs esc)))]) #`(cond clauses ... [else (#,esc)]))] diff --git a/racket/collects/racket/match/patterns.rkt b/racket/collects/racket/match/patterns.rkt index 196ca7d9c0..ca95354537 100644 --- a/racket/collects/racket/match/patterns.rkt +++ b/racket/collects/racket/match/patterns.rkt @@ -146,10 +146,13 @@ (define (merge l) (cond [(null? l) null] [(null? (cdr l)) (car l)] - [else (let ([m (make-module-identifier-mapping)]) + [else (let ([m (make-module-identifier-mapping)] + [in-order null]) (for* ([ids l] [id ids]) - (module-identifier-mapping-put! m id #t)) - (module-identifier-mapping-map m (lambda (k v) k)))])) + (unless (module-identifier-mapping-get m id (lambda () #f)) + (set! in-order (cons id in-order)) + (module-identifier-mapping-put! m id #t))) + (reverse in-order))])) ;; bound-vars : Pat -> listof identifiers (define (bound-vars p) (cond diff --git a/racket/collects/racket/private/define-et-al.rkt b/racket/collects/racket/private/define-et-al.rkt index 7dd7f7c5b3..fea6207fc0 100644 --- a/racket/collects/racket/private/define-et-al.rkt +++ b/racket/collects/racket/private/define-et-al.rkt @@ -81,7 +81,7 @@ [exprs (stx-cdr (stx-cdr code))]) (datum->syntax (quote-syntax here) - `(call/ec (lambda (,var) ,@(stx->list exprs))) + `(call-with-escape-continuation (lambda (,var) ,@(stx->list exprs))) code)) (raise-syntax-error #f diff --git a/racket/collects/racket/private/more-scheme.rkt b/racket/collects/racket/private/more-scheme.rkt index 7f110c5fbd..02e16ed2ff 100644 --- a/racket/collects/racket/private/more-scheme.rkt +++ b/racket/collects/racket/private/more-scheme.rkt @@ -303,7 +303,7 @@ (lambda (stx) (syntax-case stx () [(_ var body1 body ...) - (syntax/loc stx (call/cc (lambda (var) body1 body ...)))]))) + (syntax/loc stx (call-with-current-continuation (lambda (var) body1 body ...)))]))) (define-syntax fluid-let (lambda (stx) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index 8336f08866..a1b5d93520 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -148,6 +148,9 @@ (cdr l))) stx) (raise-syntax-error #f "bad syntax" stx))))) + + (define-values (call/cc) call-with-current-continuation) + (define-values (call/ec) call-with-escape-continuation) (#%provide (all-from-except "more-scheme.rkt" old-case fluid-let) (all-from-except "misc.rkt" collection-path collection-file-path) @@ -207,4 +210,5 @@ define-struct/derived struct-field-index struct-copy - double-flonum?)) + double-flonum? + call/cc call/ec)) diff --git a/racket/collects/racket/private/qq-and-or.rkt b/racket/collects/racket/private/qq-and-or.rkt index 03199e18e7..56cfe63b1e 100644 --- a/racket/collects/racket/private/qq-and-or.rkt +++ b/racket/collects/racket/private/qq-and-or.rkt @@ -421,7 +421,7 @@ (list (quote-syntax quote) rest) rest))))))))) - (let-values (((l0) (hash-map (syntax-e x) cons))) + (let-values (((l0) (hash-map (syntax-e x) cons #t))) (let-values (((l) (qq-hash-assocs l0 level))) (if (eq? l0 l) diff --git a/racket/collects/racket/private/sc.rkt b/racket/collects/racket/private/sc.rkt index 578293e751..ce8e282079 100644 --- a/racket/collects/racket/private/sc.rkt +++ b/racket/collects/racket/private/sc.rkt @@ -730,6 +730,7 @@ (let* ([ht (if proto-r #f (make-hasheq))] + [in-order null] ; same content as ht, but in deterministic order [l (expander p proto-r p #t (and proto-r (sub1 (length proto-r))) (if proto-r @@ -742,7 +743,9 @@ l))]) (if pr (set-mcdr! pr (cons r (mcdr pr))) - (hash-set! ht (syntax-e r) (cons (mcons r (list r)) l))))))) + (let ([pr (mcons r (list r))]) + (set! in-order (cons pr in-order)) + (hash-set! ht (syntax-e r) (cons pr l)))))))) #f)]) (if proto-r `(lambda (r) @@ -766,7 +769,7 @@ ;; This is a trick to minimize the syntax structure we keep: (quote-syntax ,(datum->syntax #f '... p))) main))) - (let ([l (apply append (hash-map ht (lambda (k v) v)))]) + (let ([l in-order]) (values ;; Get list of unique vars: (map mcar l) diff --git a/racket/collects/setup/main.rkt b/racket/collects/setup/main.rkt index 3877ac9bf7..08158b7567 100644 --- a/racket/collects/setup/main.rkt +++ b/racket/collects/setup/main.rkt @@ -120,7 +120,7 @@ (let loop ([skip-zo? (null? (use-compiled-file-paths))]) (when skip-zo? (print-bootstrapping)) - ((call/ec + ((call-with-escape-continuation (lambda (escape) ;; Create a new namespace, and also install load handlers ;; to check file dates, if necessary. diff --git a/racket/collects/syntax/parse/experimental/dset.rkt b/racket/collects/syntax/parse/experimental/dset.rkt new file mode 100644 index 0000000000..57c53e5d1c --- /dev/null +++ b/racket/collects/syntax/parse/experimental/dset.rkt @@ -0,0 +1,54 @@ +#lang racket/base + +;; A dset is an `equal?`-based set, but it preserves order based on +;; the history of additions, so that if items are added in a +;; deterministic order, they come back out in a deterministic order. + +(provide dset + dset-empty? + dset->list + dset-add + dset-union + dset-subtract + dset-filter) + +(define dset + (case-lambda + [() (hash)] + [(e) (hash e 0)])) + +(define (dset-empty? ds) + (zero? (hash-count ds))) + +(define (dset->list ds) + (map cdr + (sort (for/list ([(k v) (in-hash ds)]) + (cons v k)) + < + #:key car))) + +(define (dset-add ds e) + (if (hash-ref ds e #f) + ds + (hash-set ds e (hash-count ds)))) + +(define (dset-union ds1 ds2) + (cond + [((hash-count ds1) . > . (hash-count ds2)) + (dset-union ds2 ds1)] + [else + (for/fold ([ds2 ds2]) ([e (dset->list ds1)]) + (dset-add ds2 e))])) + +(define (dset-subtract ds1 ds2) + ;; ! takes O(size(ds2)) time ! + (for/fold ([r (dset)]) ([e (in-list (dset->list ds1))]) + (if (hash-ref ds2 e #f) + r + (dset-add r e)))) + +(define (dset-filter ds pred) + (for/fold ([r (dset)]) ([e (in-list (dset->list ds))]) + (if (pred e) + (dset-add r e) + r))) diff --git a/racket/collects/syntax/parse/experimental/template.rkt b/racket/collects/syntax/parse/experimental/template.rkt index 609135b15f..d415813f97 100644 --- a/racket/collects/syntax/parse/experimental/template.rkt +++ b/racket/collects/syntax/parse/experimental/template.rkt @@ -1,6 +1,6 @@ #lang racket/base (require (for-syntax racket/base - racket/set + "dset.rkt" racket/syntax syntax/parse/private/minimatch racket/private/stx ;; syntax/stx @@ -229,19 +229,19 @@ instead of integers and integer vectors. (if loc-id (let* ([loc-sm (make-syntax-mapping 0 loc-id)] [loc-pvar (pvar loc-sm #f #f)]) - (values (set-union drivers (set loc-pvar)) + (values (dset-add drivers loc-pvar) (relocate-guide pre-guide loc-pvar))) (values drivers pre-guide))]) - (let* ([main-env (set->env drivers (hash))] + (let* ([main-env (dset->env drivers (hash))] [guide (guide-resolve-env pre-guide main-env)]) (values guide (index-hash->vector main-env) props-guide)))) - ;; set->env : (setof env-entry) -> hash[env-entry => nat] - (define (set->env drivers init-env) + ;; dset->env : (dsetof env-entry) -> hash[env-entry => nat] + (define (dset->env drivers init-env) (for/fold ([env init-env]) - ([pvar (in-set drivers)] + ([pvar (in-list (dset->list drivers))] [n (in-naturals (+ 1 (hash-count init-env)))]) (hash-set env pvar n))) @@ -265,7 +265,7 @@ instead of integers and integer vectors. (let-values ([(sub-loop-env r-uptos) (for/fold ([env (hash)] [r-uptos null]) ([new-hdrivers (in-list new-hdrivers/level)]) - (let ([new-env (set->env new-hdrivers env)]) + (let ([new-env (dset->env new-hdrivers env)]) (values new-env (cons (hash-count new-env) r-uptos))))]) (let ([sub-loop-vector (index-hash->vector sub-loop-env get-index)]) (vector 'dots @@ -414,7 +414,7 @@ instead of integers and integer vectors. (define (list-guide . gs) (foldr cons-guide '_ gs)) - ;; parse-t : stx nat boolean -> (values (setof env-entry) pre-guide props-guide) + ;; parse-t : stx nat boolean -> (values (dsetof env-entry) pre-guide props-guide) (define (parse-t t depth esc?) (syntax-case t (?? ?@ unsyntax quasitemplate) [id @@ -430,18 +430,18 @@ instead of integers and integer vectors. [else (let ([pvar (lookup #'id depth)]) (cond [(pvar? pvar) - (values (set pvar) pvar '_)] + (values (dset pvar) pvar '_)] [(template-metafunction? pvar) (wrong-syntax t "illegal use of syntax metafunction")] [else - (wrap-props #'id (set) '_ '_)]))])] + (wrap-props #'id (dset) '_ '_)]))])] [(mf . template) (and (not esc?) (identifier? #'mf) (template-metafunction? (lookup #'mf #f))) (let-values ([(mf) (lookup #'mf #f)] [(drivers guide props-guide) (parse-t #'template depth esc?)]) - (values (set-union (set mf) drivers) + (values (dset-add drivers mf) (vector 'metafun mf guide) (cons-guide '_ props-guide)))] [(unsyntax t1) @@ -452,7 +452,7 @@ instead of integers and integer vectors. (set-box! qval (cons (cons #'tmp t) (unbox qval))) (let* ([fake-sm (make-syntax-mapping 0 #'tmp)] [fake-pvar (pvar fake-sm #f #f)]) - (values (set fake-pvar) (vector 'unsyntax fake-pvar) '_)))] + (values (dset fake-pvar) (vector 'unsyntax fake-pvar) '_)))] [else (parameterize ((quasi (car qval))) (let-values ([(drivers guide props-guide) (parse-t #'t1 depth esc?)]) @@ -479,7 +479,7 @@ instead of integers and integer vectors. (not esc?) (let-values ([(drivers1 guide1 props-guide1) (parse-t #'t1 depth esc?)] [(drivers2 guide2 props-guide2) (parse-t #'t2 depth esc?)]) - (values (set-union drivers1 drivers2) + (values (dset-union drivers1 drivers2) (vector 'orelse guide1 guide2) (list-guide '_ props-guide1 props-guide2)))] [(head DOTS . tail) @@ -496,26 +496,26 @@ instead of integers and integer vectors. (parse-h #'head (+ depth nesting) esc?)] [(tdrivers tguide tprops-guide) (parse-t tail depth esc?)]) - (when (set-empty? hdrivers) + (when (dset-empty? hdrivers) (wrong-syntax #'head "no pattern variables before ellipsis in template")) - (when (set-empty? (set-filter hdrivers (pvar/dd<=? depth))) + (when (dset-empty? (dset-filter hdrivers (pvar/dd<=? depth))) ;; FIXME: improve error message? (let ([bad-dots ;; select the nestingth (last) ellipsis as the bad one (stx-car (stx-drop nesting t))]) (wrong-syntax bad-dots "too many ellipses in template"))) (wrap-props t - (set-union hdrivers tdrivers) + (dset-union hdrivers tdrivers) ;; pre-guide hdrivers is (listof (setof pvar)) ;; set of pvars new to each level (let* ([hdrivers/level (for/list ([i (in-range nesting)]) - (set-filter hdrivers (pvar/dd<=? (+ depth i))))] + (dset-filter hdrivers (pvar/dd<=? (+ depth i))))] [new-hdrivers/level - (let loop ([raw hdrivers/level] [last (set)]) + (let loop ([raw hdrivers/level] [last (dset)]) (cond [(null? raw) null] [else - (cons (set-subtract (car raw) last) + (cons (dset-subtract (car raw) last) (loop (cdr raw) (car raw)))]))]) (vector 'dots hguide new-hdrivers/level nesting #f tguide)) (cons-guide hprops-guide (cons-guide '_ tprops-guide)))))] @@ -525,7 +525,7 @@ instead of integers and integer vectors. [(tdrivers tguide tprops-guide) (parse-t #'tail depth esc?)]) (wrap-props t - (set-union hdrivers tdrivers) + (dset-union hdrivers tdrivers) (cond [(and (eq? hguide '_) (eq? tguide '_)) '_] [hsplice? (vector 'app hguide tguide)] [else (cons hguide tguide)]) @@ -551,9 +551,9 @@ instead of integers and integer vectors. (if (eq? guide '_) '_ (vector 'box guide)) (if (eq? props-guide '_) '_ (vector 'box props-guide))))] [const - (wrap-props t (set) '_ '_)])) + (wrap-props t (dset) '_ '_)])) - ;; parse-h : stx nat boolean -> (values (setof env-entry) boolean pre-head-guide props-guide) + ;; parse-h : stx nat boolean -> (values (dsetof env-entry) boolean pre-head-guide props-guide) (define (parse-h h depth esc?) (syntax-case h (?? ?@ unsyntax-splicing) [(?? t) @@ -567,7 +567,7 @@ instead of integers and integer vectors. (not esc?) (let-values ([(drivers1 splice?1 guide1 props-guide1) (parse-h #'t1 depth esc?)] [(drivers2 splice?2 guide2 props-guide2) (parse-h #'t2 depth esc?)]) - (values (set-union drivers1 drivers2) + (values (dset-union drivers1 drivers2) (or splice?1 splice?2) (vector (if (or splice?1 splice?2) 'orelse-h 'orelse) guide1 guide2) @@ -584,7 +584,7 @@ instead of integers and integer vectors. (set-box! qval (cons (cons #'tmp h) (unbox qval))) (let* ([fake-sm (make-syntax-mapping 0 #'tmp)] [fake-pvar (pvar fake-sm #f #f)]) - (values (set fake-pvar) #t (vector 'unsyntax-splicing fake-pvar) '_)))] + (values (dset fake-pvar) #t (vector 'unsyntax-splicing fake-pvar) '_)))] [else (parameterize ((quasi (car qval))) (let*-values ([(drivers guide props-guide) (parse-t #'t1 depth esc?)] @@ -598,10 +598,6 @@ instead of integers and integer vectors. (let-values ([(drivers guide props-guide) (parse-t #'t depth esc?)]) (values drivers #f guide props-guide))])) - ;; Note: always creates equal?-based set. - (define (set-filter s pred?) - (for/set ([el (in-set s)] #:when (pred? el)) el)) - (define (lookup id depth) (let ([v (syntax-local-value id (lambda () #f))]) (cond [(syntax-pattern-variable? v) diff --git a/racket/collects/syntax/parse/private/rep-attrs.rkt b/racket/collects/syntax/parse/private/rep-attrs.rkt index bf46b9f331..746b340198 100644 --- a/racket/collects/syntax/parse/private/rep-attrs.rkt +++ b/racket/collects/syntax/parse/private/rep-attrs.rkt @@ -89,13 +89,16 @@ of signatures easier for reified syntax-classes. (define count-t (make-bound-id-table)) (define attr-t (make-bound-id-table)) (define list-count (length attrss)) + (define attr-keys null) (for* ([attrs (in-list attrss)] [attr (in-list attrs)]) (define name (attr-name attr)) (define prev (bound-id-table-ref attr-t name #f)) + (unless prev (set! attr-keys (cons name attr-keys))) (bound-id-table-set! attr-t name (join-attrs attr prev)) (let ([pc (bound-id-table-ref count-t name 0)]) (bound-id-table-set! count-t name (add1 pc)))) - (for/list ([a (in-list (bound-id-table-map attr-t (lambda (_ v) v)))]) + (for/list ([k (in-list attr-keys)]) + (define a (bound-id-table-ref attr-t k)) (if (= (bound-id-table-ref count-t (attr-name a)) list-count) a (attr-make-uncertain a)))) diff --git a/racket/src/racket/gc2/check-sdep.rkt b/racket/src/racket/gc2/check-sdep.rkt index e2a0f8a1b6..0f5ff1b12d 100644 --- a/racket/src/racket/gc2/check-sdep.rkt +++ b/racket/src/racket/gc2/check-sdep.rkt @@ -12,7 +12,7 @@ [(regexp-match? #rx"[.][ch]$" path) (define-values (ts) (file-or-directory-modify-seconds path)) (define-values (sdep) (path-replace-suffix path ".sdep")) - (call/ec + (call-with-escape-continuation (lambda (esc) (with-continuation-mark exception-handler-key diff --git a/racket/src/racket/gc2/xform.rkt b/racket/src/racket/gc2/xform.rkt index 1f731af3fc..93274506d1 100644 --- a/racket/src/racket/gc2/xform.rkt +++ b/racket/src/racket/gc2/xform.rkt @@ -71,7 +71,7 @@ ;; In case multiple xforms run in parallel, use a lock file ;; so that only one is building. (let ([lock-file "XFORM-LOCK"]) - ((call/ec + ((call-with-escape-continuation (lambda (escape) (parameterize ([uncaught-exception-handler (lambda (exn) diff --git a/racket/src/racket/src/bool.c b/racket/src/racket/src/bool.c index 759b895b54..9781955772 100644 --- a/racket/src/racket/src/bool.c +++ b/racket/src/racket/src/bool.c @@ -858,19 +858,19 @@ int is_equal (Scheme_Object *obj1, Scheme_Object *obj2, Equal_Info *eql) } case scheme_module_index_type: { - if (!eql->eq_for_modidx) { - Scheme_Modidx *midx1, *midx2; + Scheme_Modidx *midx1, *midx2; # include "mzeqchk.inc" - midx1 = (Scheme_Modidx *)obj1; - midx2 = (Scheme_Modidx *)obj2; - if (is_equal(midx1->path, midx2->path, eql)) { - obj1 = midx1->base; - obj2 = midx2->base; - goto top; - } else - return 0; - } else + midx1 = (Scheme_Modidx *)obj1; + midx2 = (Scheme_Modidx *)obj2; + if (eql->eq_for_modidx + && (SCHEME_FALSEP(midx1->path) + || SCHEME_FALSEP(midx2->path))) return 0; + else if (is_equal(midx1->path, midx2->path, eql)) { + obj1 = midx1->base; + obj2 = midx2->base; + goto top; + } } case scheme_scope_table_type: { diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index 5f7de25852..4fac159c22 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -944,7 +944,7 @@ Scheme_Object *scheme_hash_module_variable(Scheme_Env *env, Scheme_Object *modid Scheme_Hash_Table *ht; if (!env->modvars) { - ht = scheme_make_hash_table(SCHEME_hash_ptr); + ht = scheme_make_hash_table_equal_modix_eq(); env->modvars = ht; } diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index a415534ec3..7f2b33898f 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,1053 +1,1052 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,54,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,0,1,0,0,8,0, -18,0,22,0,29,0,36,0,41,0,46,0,51,0,63,0,66,0,73,0,86, -0,90,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159,0, -173,0,180,0,202,0,204,0,218,0,246,0,251,0,254,0,35,1,42,1,114, -1,121,1,132,1,141,1,174,1,207,1,13,2,18,2,99,2,104,2,109,2, -130,2,27,3,48,3,101,3,170,3,239,3,129,4,21,5,32,5,115,5,0, -0,144,7,0,0,3,1,5,105,110,115,112,48,71,35,37,109,105,110,45,115, -116,120,29,11,11,11,68,108,101,116,114,101,99,68,100,101,102,105,110,101,66, -99,111,110,100,66,119,104,101,110,66,108,101,116,42,73,108,101,116,42,45,118, -97,108,117,101,115,64,111,114,68,117,110,108,101,115,115,74,112,97,114,97,109, -101,116,101,114,105,122,101,65,108,101,116,65,97,110,100,70,104,101,114,101,45, +18,0,22,0,26,0,31,0,38,0,42,0,47,0,59,0,66,0,69,0,82, +0,89,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159,0, +173,0,180,0,202,0,204,0,218,0,246,0,251,0,255,0,72,1,79,1,90, +1,128,1,135,1,144,1,177,1,210,1,16,2,21,2,102,2,107,2,112,2, +133,2,30,3,51,3,104,3,173,3,242,3,132,4,24,5,35,5,118,5,0, +0,147,7,0,0,3,1,5,105,110,115,112,48,71,35,37,109,105,110,45,115, +116,120,29,11,11,11,65,97,110,100,66,99,111,110,100,68,100,101,102,105,110, +101,65,108,101,116,66,108,101,116,42,73,108,101,116,42,45,118,97,108,117,101, +115,68,108,101,116,114,101,99,64,111,114,74,112,97,114,97,109,101,116,101,114, +105,122,101,68,117,110,108,101,115,115,66,119,104,101,110,70,104,101,114,101,45, 115,116,120,67,113,117,111,116,101,29,94,2,16,70,35,37,107,101,114,110,101, 108,11,29,94,2,16,70,35,37,112,97,114,97,109,122,11,64,105,102,67,98, 101,103,105,110,72,108,101,116,45,118,97,108,117,101,115,63,120,75,108,101,116, 114,101,99,45,118,97,108,117,101,115,68,108,97,109,98,100,97,1,20,112,97, 114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,63,118,75, 100,101,102,105,110,101,45,118,97,108,117,101,115,38,28,16,3,93,16,2,29, -11,11,11,2,3,2,29,93,143,16,5,40,2,31,39,2,33,2,2,39,38, -29,93,2,30,36,30,39,36,31,144,40,143,2,32,16,4,2,17,40,39,2, -1,16,2,2,15,93,143,2,32,147,2,1,2,3,40,2,15,143,2,3,40, -2,15,38,32,143,2,31,2,29,36,33,145,40,143,2,34,16,4,2,17,39, -39,2,1,143,2,34,16,4,2,18,39,39,2,1,16,22,2,14,2,35,2, -12,2,35,2,5,2,35,2,10,2,35,2,6,2,35,2,13,2,35,2,11, -2,35,2,8,2,35,2,9,2,35,2,7,2,35,2,4,2,35,38,34,143, -2,33,2,29,38,35,93,143,2,34,143,2,1,2,3,18,143,66,104,101,114, -101,2,28,27,248,22,166,4,195,249,22,159,4,80,143,42,39,251,22,92,2, -19,248,22,104,199,12,249,22,82,2,20,248,22,106,201,27,248,22,166,4,195, -249,22,159,4,80,143,42,39,251,22,92,2,19,248,22,104,199,249,22,82,2, -20,248,22,106,201,12,27,248,22,84,248,22,166,4,196,28,248,22,90,193,20, -14,144,40,39,40,28,248,22,90,248,22,84,194,248,22,163,20,193,249,22,159, -4,80,143,42,39,251,22,92,2,19,248,22,163,20,199,249,22,82,2,14,248, -22,164,20,201,11,18,143,10,2,28,27,248,22,84,248,22,166,4,196,28,248, -22,90,193,20,14,144,40,39,40,28,248,22,90,248,22,84,194,248,22,163,20, -193,249,22,159,4,80,143,42,39,250,22,92,2,21,248,22,92,249,22,92,248, -22,92,2,22,248,22,163,20,201,251,22,92,2,19,2,22,2,22,249,22,82, -2,10,248,22,164,20,204,18,143,11,2,28,248,22,166,4,193,27,248,22,166, -4,194,249,22,82,248,22,92,248,22,83,196,248,22,164,20,195,27,248,22,84, -248,22,166,4,23,197,1,249,22,159,4,80,143,42,39,28,248,22,66,248,22, -160,4,248,22,83,23,198,2,27,249,22,2,32,0,88,148,8,36,40,46,11, -9,222,33,43,248,22,166,4,248,22,104,23,200,2,250,22,92,2,23,248,22, -92,249,22,92,248,22,92,248,22,163,20,23,204,2,250,22,93,2,24,249,22, -2,22,83,23,204,2,248,22,106,23,206,2,249,22,82,248,22,163,20,23,202, -1,249,22,2,22,104,23,200,1,250,22,93,2,21,249,22,2,32,0,88,148, -8,36,40,50,11,9,222,33,44,248,22,166,4,248,22,163,20,201,248,22,164, -20,198,27,248,22,166,4,194,249,22,82,248,22,92,248,22,83,196,248,22,164, -20,195,27,248,22,84,248,22,166,4,23,197,1,249,22,159,4,80,143,42,39, -250,22,93,2,23,249,22,2,32,0,88,148,8,36,40,50,11,9,222,33,46, -248,22,166,4,248,22,83,201,248,22,164,20,198,27,248,22,84,248,22,166,4, -196,27,248,22,166,4,248,22,83,195,249,22,159,4,80,143,43,39,28,248,22, -90,195,250,22,93,2,21,9,248,22,164,20,199,250,22,92,2,13,248,22,92, -248,22,83,199,250,22,93,2,8,248,22,164,20,201,248,22,164,20,202,27,248, -22,84,248,22,166,4,196,27,248,22,166,4,248,22,83,195,249,22,159,4,80, -143,43,39,28,248,22,90,195,250,22,93,2,21,9,248,22,164,20,199,250,22, -92,2,21,248,22,92,248,22,83,199,250,22,93,2,9,248,22,164,20,201,248, -22,164,20,202,27,248,22,84,248,22,166,4,23,197,1,27,249,22,1,22,96, -249,22,2,22,166,4,248,22,166,4,248,22,83,199,248,22,187,4,249,22,159, -4,80,143,44,39,251,22,92,1,22,119,105,116,104,45,99,111,110,116,105,110, -117,97,116,105,111,110,45,109,97,114,107,2,25,250,22,93,1,23,101,120,116, -101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,21, -95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97,114,107,45, -115,101,116,45,102,105,114,115,116,11,2,25,202,250,22,93,2,21,9,248,22, -164,20,204,27,248,22,84,248,22,166,4,196,28,248,22,90,193,20,14,144,40, -39,40,249,22,159,4,80,143,42,39,27,248,22,166,4,248,22,83,197,28,249, -22,171,9,64,61,62,248,22,160,4,248,22,104,196,250,22,92,2,21,248,22, -92,249,22,92,21,93,2,26,248,22,163,20,199,250,22,93,2,6,249,22,92, -2,26,249,22,92,248,22,113,203,2,26,248,22,164,20,202,251,22,92,2,19, -28,249,22,171,9,248,22,160,4,248,22,163,20,200,66,101,108,115,101,10,248, -22,163,20,197,250,22,93,2,21,9,248,22,164,20,200,249,22,82,2,6,248, -22,164,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22,84,248,22, -166,4,196,249,22,159,4,80,143,42,39,28,248,22,66,248,22,160,4,248,22, -83,197,250,22,92,2,27,248,22,92,248,22,163,20,199,248,22,104,198,27,248, -22,160,4,248,22,163,20,197,250,22,92,2,27,248,22,92,248,22,83,197,250, -22,93,2,24,248,22,164,20,199,248,22,164,20,202,144,39,20,120,145,2,1, -39,16,1,11,16,0,20,26,15,61,9,2,2,2,2,2,3,11,11,11,11, -9,9,11,11,11,10,39,80,143,39,39,20,120,145,2,1,39,16,0,16,0, -41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4,2,5,2,6,2, -7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,16,11,11,11,11,11, -11,11,11,11,11,11,11,16,11,2,4,2,5,2,6,2,7,2,8,2,9, -2,10,2,11,2,12,2,13,2,14,39,50,40,16,0,39,16,1,2,15,40, -11,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0, -39,39,16,12,16,5,11,20,15,16,2,20,14,144,39,39,40,80,143,39,39, -39,20,120,145,2,1,39,16,1,2,15,16,1,33,36,10,16,5,2,11,88, -148,8,36,40,56,40,9,223,0,33,37,39,20,120,145,2,1,39,16,1,2, -15,16,0,11,16,5,2,7,88,148,8,36,40,56,40,9,223,0,33,38,39, -20,120,145,2,1,39,16,1,2,15,16,0,11,16,5,2,14,88,148,8,36, -40,56,42,9,223,0,33,39,39,20,120,145,2,1,39,16,1,2,15,16,1, -33,40,11,16,5,2,10,88,148,8,36,40,59,42,9,223,0,33,41,39,20, -120,145,2,1,39,16,1,2,15,16,1,33,42,11,16,5,2,13,88,148,8, -36,40,61,40,9,223,0,33,45,39,20,120,145,2,1,39,16,1,2,15,16, -0,11,16,5,2,4,88,148,8,36,40,56,40,9,223,0,33,47,39,20,120, -145,2,1,39,16,1,2,15,16,0,11,16,5,2,8,88,148,8,36,40,57, -40,9,223,0,33,48,39,20,120,145,2,1,39,16,1,2,15,16,0,11,16, -5,2,9,88,148,8,36,40,57,40,9,223,0,33,49,39,20,120,145,2,1, -39,16,1,2,15,16,0,11,16,5,2,12,88,148,8,36,40,59,40,9,223, -0,33,50,39,20,120,145,2,1,39,16,1,2,15,16,0,11,16,5,2,6, -88,148,8,36,40,61,42,9,223,0,33,51,39,20,120,145,2,1,39,16,1, -2,15,16,1,33,52,11,16,5,2,5,88,148,8,36,40,57,40,9,223,0, -33,53,39,20,120,145,2,1,39,16,1,2,15,16,0,11,16,0,94,2,17, -2,18,93,2,17,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 2088); +11,11,11,2,3,2,29,93,143,16,5,39,2,31,40,2,34,2,2,39,38, +29,93,2,30,36,30,0,39,36,31,1,145,40,143,2,32,16,4,2,17,39, +39,2,1,143,2,32,16,4,2,18,39,39,2,1,16,22,2,4,2,33,2, +5,2,33,2,6,2,33,2,7,2,33,2,8,2,33,2,9,2,33,2,10, +2,33,2,11,2,33,2,12,2,33,2,13,2,33,2,14,2,33,38,32,143, +2,31,2,29,38,33,93,143,2,32,143,2,1,2,3,36,34,2,144,40,143, +2,35,16,4,2,17,40,39,2,1,16,2,2,15,93,143,2,35,147,2,1, +2,3,40,2,15,143,2,3,40,2,15,38,35,143,2,34,2,29,18,143,66, +104,101,114,101,2,28,27,248,22,164,4,195,249,22,157,4,80,143,42,39,251, +22,90,2,19,248,22,102,199,12,249,22,80,2,20,248,22,104,201,27,248,22, +164,4,195,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,102,199,249, +22,80,2,20,248,22,104,201,12,27,248,22,82,248,22,164,4,196,28,248,22, +88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,161,20,193, +249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,161,20,199,249,22,80, +2,4,248,22,162,20,201,11,18,143,10,2,28,27,248,22,82,248,22,164,4, +196,28,248,22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248, +22,161,20,193,249,22,157,4,80,143,42,39,250,22,90,2,21,248,22,90,249, +22,90,248,22,90,2,22,248,22,161,20,201,251,22,90,2,19,2,22,2,22, +249,22,80,2,11,248,22,162,20,204,18,143,11,2,28,248,22,164,4,193,27, +248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22,162,20,195,27, +248,22,82,248,22,164,4,23,197,1,249,22,157,4,80,143,42,39,28,248,22, +64,248,22,158,4,248,22,81,23,198,2,27,249,22,2,32,0,88,148,8,36, +40,46,11,9,222,33,43,248,22,164,4,248,22,102,23,200,2,250,22,90,2, +23,248,22,90,249,22,90,248,22,90,248,22,161,20,23,204,2,250,22,91,2, +24,249,22,2,22,81,23,204,2,248,22,104,23,206,2,249,22,80,248,22,161, +20,23,202,1,249,22,2,22,102,23,200,1,250,22,91,2,21,249,22,2,32, +0,88,148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,161,20,201, +248,22,162,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196, +248,22,162,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80, +143,42,39,250,22,91,2,23,249,22,2,32,0,88,148,8,36,40,50,11,9, +222,33,46,248,22,164,4,248,22,81,201,248,22,162,20,198,27,248,22,82,248, +22,164,4,196,27,248,22,164,4,248,22,81,195,249,22,157,4,80,143,43,39, +28,248,22,88,195,250,22,91,2,21,9,248,22,162,20,199,250,22,90,2,7, +248,22,90,248,22,81,199,250,22,91,2,8,248,22,162,20,201,248,22,162,20, +202,27,248,22,82,248,22,164,4,196,27,248,22,164,4,248,22,81,195,249,22, +157,4,80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,162,20, +199,250,22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,162, +20,201,248,22,162,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249,22, +1,22,94,249,22,2,22,164,4,248,22,164,4,248,22,81,199,248,22,185,4, +249,22,157,4,80,143,44,39,251,22,90,1,22,119,105,116,104,45,99,111,110, +116,105,110,117,97,116,105,111,110,45,109,97,114,107,2,25,250,22,91,1,23, +101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105, +111,110,21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97, +114,107,45,115,101,116,45,102,105,114,115,116,11,2,25,202,250,22,91,2,21, +9,248,22,162,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193,20, +14,144,40,39,40,249,22,157,4,80,143,42,39,27,248,22,164,4,248,22,81, +197,28,249,22,169,9,64,61,62,248,22,158,4,248,22,102,196,250,22,90,2, +21,248,22,90,249,22,90,21,93,2,26,248,22,161,20,199,250,22,91,2,5, +249,22,90,2,26,249,22,90,248,22,111,203,2,26,248,22,162,20,202,251,22, +90,2,19,28,249,22,169,9,248,22,158,4,248,22,161,20,200,66,101,108,115, +101,10,248,22,161,20,197,250,22,91,2,21,9,248,22,162,20,200,249,22,80, +2,5,248,22,162,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22, +82,248,22,164,4,196,249,22,157,4,80,143,42,39,28,248,22,64,248,22,158, +4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,161,20,199,248,22,102, +198,27,248,22,158,4,248,22,161,20,197,250,22,90,2,27,248,22,90,248,22, +81,197,250,22,91,2,24,248,22,162,20,199,248,22,162,20,202,144,39,20,121, +145,2,1,39,16,1,11,16,0,20,27,15,61,9,2,2,2,2,2,3,11, +11,11,11,9,9,11,11,11,10,39,80,143,39,39,20,121,145,2,1,39,16, +0,16,0,41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4,2,5, +2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,16,11,11, +11,11,11,11,11,11,11,11,11,11,16,11,2,4,2,5,2,6,2,7,2, +8,2,9,2,10,2,11,2,12,2,13,2,14,39,50,40,16,0,39,16,1, +2,15,40,11,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16, +0,16,0,39,39,16,12,16,5,11,20,15,16,2,20,14,144,39,39,40,80, +143,39,39,39,20,121,145,2,1,39,16,1,2,15,16,1,33,36,10,16,5, +2,13,88,148,8,36,40,56,40,9,223,0,33,37,39,20,121,145,2,1,39, +16,1,2,15,16,0,11,16,5,2,14,88,148,8,36,40,56,40,9,223,0, +33,38,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,4,88, +148,8,36,40,56,42,9,223,0,33,39,39,20,121,145,2,1,39,16,1,2, +15,16,1,33,40,11,16,5,2,11,88,148,8,36,40,59,42,9,223,0,33, +41,39,20,121,145,2,1,39,16,1,2,15,16,1,33,42,11,16,5,2,7, +88,148,8,36,40,61,40,9,223,0,33,45,39,20,121,145,2,1,39,16,1, +2,15,16,0,11,16,5,2,10,88,148,8,36,40,56,40,9,223,0,33,47, +39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,8,88,148,8, +36,40,57,40,9,223,0,33,48,39,20,121,145,2,1,39,16,1,2,15,16, +0,11,16,5,2,9,88,148,8,36,40,57,40,9,223,0,33,49,39,20,121, +145,2,1,39,16,1,2,15,16,0,11,16,5,2,12,88,148,8,36,40,59, +40,9,223,0,33,50,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16, +5,2,5,88,148,8,36,40,61,42,9,223,0,33,51,39,20,121,145,2,1, +39,16,1,2,15,16,1,33,52,11,16,5,2,6,88,148,8,36,40,57,40, +9,223,0,33,53,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,0, +94,2,17,2,18,93,2,17,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 2091); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,54,84,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,194,0,0,0,1,0,0,8,0, -16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,173,0,180, -0,195,0,213,0,225,0,241,0,255,0,21,1,41,1,48,1,82,1,99,1, -116,1,139,1,154,1,193,1,211,1,242,1,254,1,15,2,27,2,42,2,66, -2,98,2,127,2,143,2,161,2,181,2,202,2,220,2,251,2,9,3,26,3, -70,3,78,3,83,3,127,3,134,3,144,3,159,3,168,3,173,3,175,3,208, -3,232,3,253,3,10,4,20,4,29,4,40,4,58,4,71,4,81,4,91,4, -97,4,102,4,114,4,117,4,121,4,126,4,169,4,182,4,185,4,209,4,248, -4,255,4,12,5,34,5,45,5,75,5,98,5,106,5,130,5,151,5,95,6, -125,6,206,9,229,9,246,9,170,11,17,12,31,12,235,12,211,14,220,14,229, -14,243,14,253,14,14,16,117,16,230,16,47,17,120,17,224,17,253,17,68,18, -206,18,21,19,234,19,96,20,109,20,227,20,240,20,79,21,146,21,159,21,170, -21,66,22,184,22,228,22,83,23,161,25,185,25,47,26,129,27,136,27,188,27, -203,27,194,28,210,28,65,29,224,29,231,29,109,31,186,31,203,31,103,32,123, -32,183,32,190,32,50,33,104,33,123,33,74,34,90,34,51,35,40,36,77,36, -86,36,163,37,8,40,24,40,91,40,112,40,132,40,152,40,209,40,169,43,135, -44,151,44,122,45,180,45,213,45,89,46,248,46,8,47,105,47,122,47,200,49, -251,51,11,52,241,53,173,54,175,54,202,54,218,54,234,54,75,55,142,56,74, -57,90,57,99,57,106,57,172,58,238,59,100,60,146,63,20,64,152,64,97,66, -47,67,89,67,197,67,0,0,144,75,0,0,3,1,5,105,110,115,112,48,69, -35,37,117,116,105,108,115,74,112,97,116,104,45,115,116,114,105,110,103,63,66, -98,115,98,115,78,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116,104, -73,114,101,114,111,111,116,45,112,97,116,104,1,20,102,105,110,100,45,101,120, -101,99,117,116,97,98,108,101,45,112,97,116,104,1,27,112,97,116,104,45,108, -105,115,116,45,115,116,114,105,110,103,45,62,112,97,116,104,45,108,105,115,116, -1,42,99,97,108,108,45,119,105,116,104,45,100,101,102,97,117,108,116,45,114, -101,97,100,105,110,103,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105, -111,110,67,113,117,111,116,101,70,35,37,112,97,114,97,109,122,29,94,2,10, -2,11,11,76,45,99,104,101,99,107,45,114,101,108,112,97,116,104,79,45,99, -104,101,99,107,45,99,111,108,108,101,99,116,105,111,110,73,45,99,104,101,99, -107,45,102,97,105,108,77,99,111,108,108,101,99,116,105,111,110,45,112,97,116, -104,75,102,105,110,100,45,99,111,108,45,102,105,108,101,1,20,99,111,108,108, -101,99,116,105,111,110,45,102,105,108,101,45,112,97,116,104,1,18,102,105,110, -100,45,109,97,105,110,45,99,111,108,108,101,99,116,115,29,94,2,10,2,11, -11,1,32,101,120,101,45,114,101,108,97,116,105,118,101,45,112,97,116,104,45, -62,99,111,109,112,108,101,116,101,45,112,97,116,104,78,102,105,110,100,45,109, -97,105,110,45,99,111,110,102,105,103,78,103,101,116,45,99,111,110,102,105,103, -45,116,97,98,108,101,1,21,103,101,116,45,105,110,115,116,97,108,108,97,116, -105,111,110,45,110,97,109,101,76,99,111,101,114,99,101,45,116,111,45,112,97, -116,104,1,37,99,111,108,108,101,99,116,115,45,114,101,108,97,116,105,118,101, -45,112,97,116,104,45,62,99,111,109,112,108,101,116,101,45,112,97,116,104,79, -97,100,100,45,99,111,110,102,105,103,45,115,101,97,114,99,104,1,29,102,105, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,1,0,0,8,0, +16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,178,0,193, +0,211,0,223,0,239,0,253,0,19,1,39,1,73,1,90,1,107,1,130,1, +145,1,184,1,202,1,233,1,245,1,6,2,18,2,33,2,57,2,89,2,118, +2,134,2,152,2,172,2,193,2,211,2,242,2,0,3,17,3,61,3,69,3, +74,3,118,3,125,3,135,3,150,3,159,3,164,3,166,3,199,3,223,3,244, +3,1,4,11,4,20,4,31,4,49,4,62,4,72,4,82,4,88,4,93,4, +105,4,108,4,112,4,117,4,160,4,173,4,176,4,200,4,239,4,246,4,3, +5,25,5,36,5,66,5,89,5,97,5,121,5,142,5,86,6,116,6,197,9, +220,9,237,9,161,11,8,12,22,12,226,12,202,14,211,14,220,14,234,14,244, +14,5,16,108,16,221,16,38,17,111,17,215,17,244,17,59,18,197,18,12,19, +225,19,87,20,100,20,218,20,231,20,70,21,137,21,150,21,161,21,57,22,175, +22,219,22,74,23,152,25,176,25,38,26,120,27,127,27,179,27,192,27,182,28, +198,28,53,29,212,29,219,29,96,31,173,31,190,31,90,32,110,32,170,32,177, +32,37,33,91,33,110,33,61,34,77,34,38,35,27,36,64,36,73,36,150,37, +251,39,11,40,78,40,99,40,119,40,139,40,196,40,156,43,122,44,138,44,109, +45,167,45,200,45,76,46,235,46,251,46,92,47,109,47,187,49,238,51,254,51, +228,53,160,54,162,54,189,54,205,54,221,54,62,55,129,56,61,57,77,57,86, +57,93,57,159,58,225,59,87,60,133,63,7,64,139,64,84,66,34,67,76,67, +184,67,0,0,131,75,0,0,3,1,5,105,110,115,112,48,69,35,37,117,116, +105,108,115,74,112,97,116,104,45,115,116,114,105,110,103,63,66,98,115,98,115, +78,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116,104,73,114,101,114, +111,111,116,45,112,97,116,104,1,20,102,105,110,100,45,101,120,101,99,117,116, +97,98,108,101,45,112,97,116,104,1,27,112,97,116,104,45,108,105,115,116,45, +115,116,114,105,110,103,45,62,112,97,116,104,45,108,105,115,116,1,42,99,97, +108,108,45,119,105,116,104,45,100,101,102,97,117,108,116,45,114,101,97,100,105, +110,103,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,67,113, +117,111,116,101,29,94,2,10,70,35,37,112,97,114,97,109,122,11,76,45,99, +104,101,99,107,45,114,101,108,112,97,116,104,79,45,99,104,101,99,107,45,99, +111,108,108,101,99,116,105,111,110,73,45,99,104,101,99,107,45,102,97,105,108, +77,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,75,102,105,110,100, +45,99,111,108,45,102,105,108,101,1,20,99,111,108,108,101,99,116,105,111,110, +45,102,105,108,101,45,112,97,116,104,1,18,102,105,110,100,45,109,97,105,110, +45,99,111,108,108,101,99,116,115,1,32,101,120,101,45,114,101,108,97,116,105, +118,101,45,112,97,116,104,45,62,99,111,109,112,108,101,116,101,45,112,97,116, +104,78,102,105,110,100,45,109,97,105,110,45,99,111,110,102,105,103,78,103,101, +116,45,99,111,110,102,105,103,45,116,97,98,108,101,1,21,103,101,116,45,105, +110,115,116,97,108,108,97,116,105,111,110,45,110,97,109,101,76,99,111,101,114, +99,101,45,116,111,45,112,97,116,104,1,37,99,111,108,108,101,99,116,115,45, +114,101,108,97,116,105,118,101,45,112,97,116,104,45,62,99,111,109,112,108,101, +116,101,45,112,97,116,104,79,97,100,100,45,99,111,110,102,105,103,45,115,101, +97,114,99,104,1,29,102,105,110,100,45,108,105,98,114,97,114,121,45,99,111, +108,108,101,99,116,105,111,110,45,108,105,110,107,115,73,108,105,110,107,115,45, +99,97,99,104,101,78,115,116,97,109,112,45,112,114,111,109,112,116,45,116,97, +103,73,102,105,108,101,45,62,115,116,97,109,112,76,110,111,45,102,105,108,101, +45,115,116,97,109,112,63,1,22,103,101,116,45,108,105,110,107,101,100,45,99, +111,108,108,101,99,116,105,111,110,115,1,30,110,111,114,109,97,108,105,122,101, +45,99,111,108,108,101,99,116,105,111,110,45,114,101,102,101,114,101,110,99,101, +1,27,102,105,108,101,45,101,120,105,115,116,115,63,47,109,97,121,98,101,45, +99,111,109,112,105,108,101,100,77,112,97,116,104,45,97,100,100,45,115,117,102, +102,105,120,79,99,104,101,99,107,45,115,117,102,102,105,120,45,99,97,108,108, +1,18,112,97,116,104,45,97,100,106,117,115,116,45,115,117,102,102,105,120,1, +19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102,105,120,79, +108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,1,29,102,105, 110,100,45,108,105,98,114,97,114,121,45,99,111,108,108,101,99,116,105,111,110, -45,108,105,110,107,115,73,108,105,110,107,115,45,99,97,99,104,101,78,115,116, -97,109,112,45,112,114,111,109,112,116,45,116,97,103,73,102,105,108,101,45,62, -115,116,97,109,112,76,110,111,45,102,105,108,101,45,115,116,97,109,112,63,1, -22,103,101,116,45,108,105,110,107,101,100,45,99,111,108,108,101,99,116,105,111, -110,115,1,30,110,111,114,109,97,108,105,122,101,45,99,111,108,108,101,99,116, -105,111,110,45,114,101,102,101,114,101,110,99,101,1,27,102,105,108,101,45,101, -120,105,115,116,115,63,47,109,97,121,98,101,45,99,111,109,112,105,108,101,100, -77,112,97,116,104,45,97,100,100,45,115,117,102,102,105,120,79,99,104,101,99, -107,45,115,117,102,102,105,120,45,99,97,108,108,1,18,112,97,116,104,45,97, -100,106,117,115,116,45,115,117,102,102,105,120,1,19,112,97,116,104,45,114,101, -112,108,97,99,101,45,115,117,102,102,105,120,79,108,111,97,100,47,117,115,101, -45,99,111,109,112,105,108,101,100,1,29,102,105,110,100,45,108,105,98,114,97, -114,121,45,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,115,75,101, -109,98,101,100,100,101,100,45,108,111,97,100,78,110,111,114,109,97,108,45,112, -97,116,104,45,99,97,115,101,6,41,41,40,111,114,47,99,32,112,97,116,104, -45,102,111,114,45,115,111,109,101,45,115,121,115,116,101,109,63,32,112,97,116, -104,45,115,116,114,105,110,103,63,41,69,119,105,110,100,111,119,115,6,2,2, -92,49,6,41,41,40,111,114,47,99,32,112,97,116,104,45,115,116,114,105,110, -103,63,32,112,97,116,104,45,102,111,114,45,115,111,109,101,45,115,121,115,116, -101,109,63,41,6,4,4,112,97,116,104,5,8,92,92,63,92,82,69,76,92, -6,12,12,112,97,116,104,45,115,116,114,105,110,103,63,70,114,101,108,97,116, -105,118,101,66,108,111,111,112,5,0,6,30,30,40,112,114,111,99,101,100,117, -114,101,45,97,114,105,116,121,45,105,110,99,108,117,100,101,115,47,99,32,48, -41,6,21,21,105,110,118,97,108,105,100,32,114,101,108,97,116,105,118,101,32, -112,97,116,104,6,18,18,40,97,110,121,47,99,32,46,32,45,62,32,46,32, -97,110,121,41,74,99,111,108,108,101,99,116,115,45,100,105,114,71,101,120,101, -99,45,102,105,108,101,70,111,114,105,103,45,100,105,114,72,99,111,110,102,105, -103,45,100,105,114,79,105,110,115,116,97,108,108,97,116,105,111,110,45,110,97, -109,101,6,10,10,108,105,110,107,115,46,114,107,116,100,71,97,100,100,111,110, -45,100,105,114,71,102,115,45,99,104,97,110,103,101,67,101,114,114,111,114,66, -114,111,111,116,73,115,116,97,116,105,99,45,114,111,111,116,6,0,0,6,1, -1,47,5,3,46,122,111,6,40,40,114,101,109,111,118,105,110,103,32,115,117, -102,102,105,120,32,109,97,107,101,115,32,112,97,116,104,32,101,108,101,109,101, -110,116,32,101,109,112,116,121,6,10,10,103,105,118,101,110,32,112,97,116,104, -5,1,95,6,21,21,40,111,114,47,99,32,115,116,114,105,110,103,63,32,98, -121,116,101,115,63,41,6,36,36,99,97,110,110,111,116,32,97,100,100,32,97, -32,115,117,102,102,105,120,32,116,111,32,97,32,114,111,111,116,32,112,97,116, -104,58,32,68,102,105,110,105,115,104,5,11,80,76,84,67,79,76,76,69,67, -84,83,1,20,99,111,108,108,101,99,116,115,45,115,101,97,114,99,104,45,100, -105,114,115,6,8,8,99,111,108,108,101,99,116,115,27,248,22,175,15,194,28, -192,192,28,248,22,155,7,194,27,248,22,134,16,195,28,192,192,248,22,135,16, -195,11,0,21,35,114,120,34,94,91,92,92,93,91,92,92,93,91,63,93,91, -92,92,93,34,0,6,35,114,120,34,47,34,0,22,35,114,120,34,91,47,92, -92,93,91,46,32,93,43,91,47,92,92,93,42,36,34,0,19,35,114,120,34, -91,32,46,93,43,40,91,47,92,92,93,42,41,36,34,86,94,28,28,248,22, -176,15,23,195,2,10,28,248,22,175,15,23,195,2,10,28,248,22,155,7,23, -195,2,28,248,22,134,16,23,195,2,10,248,22,135,16,23,195,2,11,12,250, -22,182,11,2,43,2,44,23,197,2,28,28,248,22,176,15,23,195,2,249,22, -171,9,248,22,177,15,23,197,2,2,45,249,22,171,9,247,22,182,8,2,45, -27,28,248,22,155,7,23,196,2,23,195,2,248,22,167,8,248,22,180,15,23, -197,2,28,249,22,172,16,2,81,23,195,2,28,248,22,155,7,195,248,22,183, -15,195,194,27,248,22,130,8,23,195,1,249,22,184,15,248,22,170,8,250,22, -180,16,2,82,28,249,22,172,16,2,83,23,201,2,23,199,1,250,22,180,16, -2,84,23,202,1,2,46,80,144,47,40,41,2,45,28,248,22,155,7,194,248, -22,183,15,194,193,0,28,35,114,120,34,94,92,92,92,92,92,92,92,92,91, -63,93,92,92,92,92,85,78,67,92,92,92,92,34,86,95,28,28,28,248,22, -175,15,23,195,2,10,28,248,22,155,7,23,195,2,28,248,22,134,16,23,195, -2,10,248,22,135,16,23,195,2,11,10,248,22,176,15,23,195,2,12,252,22, -182,11,2,6,2,47,39,23,199,2,23,200,2,28,28,28,248,22,175,15,23, -196,2,10,28,248,22,155,7,23,196,2,28,248,22,134,16,23,196,2,10,248, -22,135,16,23,196,2,11,10,248,22,176,15,23,196,2,12,252,22,182,11,2, -6,2,47,40,23,199,2,23,200,2,27,28,248,22,176,15,23,196,2,248,22, -177,15,23,196,2,247,22,178,15,86,95,28,28,248,22,136,16,23,196,2,10, -249,22,171,9,247,22,178,15,23,195,2,12,253,22,184,11,2,6,6,54,54, -112,97,116,104,32,105,115,32,110,111,116,32,99,111,109,112,108,101,116,101,32, -97,110,100,32,110,111,116,32,116,104,101,32,112,108,97,116,102,111,114,109,39, -115,32,99,111,110,118,101,110,116,105,111,110,2,48,23,201,2,6,24,24,112, -108,97,116,102,111,114,109,32,99,111,110,118,101,110,116,105,111,110,32,116,121, -112,101,247,22,178,15,28,249,22,171,9,28,248,22,176,15,23,199,2,248,22, -177,15,23,199,2,247,22,178,15,23,195,2,12,253,22,184,11,2,6,6,37, -37,103,105,118,101,110,32,112,97,116,104,115,32,117,115,101,32,100,105,102,102, -101,114,101,110,116,32,99,111,110,118,101,110,116,105,111,110,115,2,48,23,201, -2,6,9,9,114,111,111,116,32,112,97,116,104,23,202,2,27,27,248,22,140, -16,28,248,22,136,16,23,199,2,23,198,1,248,22,137,16,23,199,1,86,94, -28,28,248,22,176,15,23,194,2,10,28,248,22,175,15,23,194,2,10,28,248, -22,155,7,23,194,2,28,248,22,134,16,23,194,2,10,248,22,135,16,23,194, -2,11,12,250,22,182,11,2,43,2,44,23,196,2,28,28,248,22,176,15,23, -194,2,249,22,171,9,248,22,177,15,23,196,2,2,45,249,22,171,9,247,22, -182,8,2,45,27,28,248,22,155,7,23,195,2,23,194,2,248,22,167,8,248, -22,180,15,23,196,2,28,249,22,172,16,2,81,23,195,2,28,248,22,155,7, -194,248,22,183,15,194,193,27,248,22,130,8,23,195,1,249,22,184,15,248,22, -170,8,250,22,180,16,2,82,28,249,22,172,16,2,83,23,201,2,23,199,1, -250,22,180,16,2,84,23,202,1,2,46,80,144,50,40,41,2,45,28,248,22, -155,7,193,248,22,183,15,193,192,27,248,22,180,15,23,195,2,28,249,22,171, -9,23,197,2,66,117,110,105,120,28,249,22,152,8,194,5,1,47,28,248,22, -176,15,198,197,248,22,183,15,198,249,22,129,16,199,249,22,184,15,249,22,155, -8,248,22,180,15,200,40,198,28,249,22,171,9,23,197,2,2,45,249,22,129, -16,23,200,1,249,22,184,15,28,249,22,172,16,0,27,35,114,120,34,94,92, -92,92,92,92,92,92,92,91,63,93,92,92,92,92,91,97,45,122,93,58,34, -23,199,2,251,22,156,8,2,49,250,22,155,8,203,43,44,5,1,92,249,22, -155,8,202,45,28,249,22,172,16,2,86,23,199,2,249,22,156,8,2,49,249, -22,155,8,200,43,28,249,22,172,16,2,86,23,199,2,249,22,156,8,2,49, -249,22,155,8,200,43,28,249,22,172,16,0,14,35,114,120,34,94,92,92,92, -92,92,92,92,92,34,23,199,2,249,22,156,8,5,4,85,78,67,92,249,22, -155,8,200,41,28,249,22,172,16,0,12,35,114,120,34,94,91,97,45,122,93, -58,34,198,249,22,156,8,250,22,155,8,201,39,40,249,22,155,8,200,41,12, -198,12,32,88,88,148,8,36,42,56,11,72,102,111,117,110,100,45,101,120,101, -99,222,33,91,32,89,88,148,8,36,43,61,11,66,110,101,120,116,222,33,90, -27,248,22,138,16,23,196,2,28,249,22,173,9,23,195,2,23,197,1,11,28, -248,22,134,16,23,194,2,27,249,22,129,16,23,197,1,23,196,1,28,23,197, -2,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,2,86,95,23,195, -1,23,194,1,27,28,23,202,2,27,248,22,138,16,23,199,2,28,249,22,173, -9,23,195,2,23,200,2,11,28,248,22,134,16,23,194,2,250,2,88,23,205, -2,23,206,2,249,22,129,16,23,200,2,23,198,1,250,2,88,23,205,2,23, -206,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,175, -15,23,196,2,27,249,22,129,16,23,198,2,23,205,2,28,28,248,22,188,15, -193,10,248,22,187,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28, -23,203,2,11,27,248,22,138,16,23,200,2,28,249,22,173,9,194,23,201,1, -11,28,248,22,134,16,193,250,2,88,205,206,249,22,129,16,200,197,250,2,88, -205,206,195,192,86,94,23,194,1,28,23,196,2,90,144,42,11,89,146,42,39, -11,248,22,132,16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,201,2, -27,248,22,138,16,23,199,2,28,249,22,173,9,23,195,2,23,200,2,11,28, -248,22,134,16,23,194,2,250,2,88,23,204,2,23,205,2,249,22,129,16,23, -200,2,23,198,1,250,2,88,23,204,2,23,205,2,23,196,1,11,28,23,193, -2,192,86,94,23,193,1,27,28,248,22,175,15,23,196,2,27,249,22,129,16, -23,198,2,23,204,2,28,28,248,22,188,15,193,10,248,22,187,15,193,192,11, -11,28,23,193,2,192,86,94,23,193,1,28,23,202,2,11,27,248,22,138,16, -23,200,2,28,249,22,173,9,194,23,201,1,11,28,248,22,134,16,193,250,2, -88,204,205,249,22,129,16,200,197,250,2,88,204,205,195,192,28,23,193,2,90, -144,42,11,89,146,42,39,11,248,22,132,16,23,199,2,86,95,23,195,1,23, -194,1,27,28,23,198,2,251,2,89,23,198,2,23,203,2,23,201,2,23,202, -2,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,175,15,195,27,249, -22,129,16,197,200,28,28,248,22,188,15,193,10,248,22,187,15,193,192,11,11, -28,192,192,28,198,11,251,2,89,198,203,201,202,194,32,92,88,148,8,36,43, -60,11,2,52,222,33,93,28,248,22,90,23,197,2,11,27,249,22,129,16,248, -22,137,16,248,22,83,23,201,2,23,196,2,28,248,22,187,15,23,194,2,250, -2,88,197,198,195,86,94,23,193,1,27,248,22,164,20,23,199,1,28,248,22, -90,23,194,2,11,27,249,22,129,16,248,22,137,16,248,22,83,23,198,2,23, -198,2,28,248,22,187,15,23,194,2,250,2,88,199,200,195,86,94,23,193,1, -27,248,22,164,20,23,196,1,28,248,22,90,23,194,2,11,27,249,22,129,16, -248,22,137,16,248,22,83,23,198,2,23,200,2,28,248,22,187,15,23,194,2, -250,2,88,201,202,195,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248, -22,90,23,194,2,11,27,249,22,129,16,248,22,137,16,248,22,83,197,201,28, -248,22,187,15,193,250,2,88,203,204,195,251,2,92,203,204,205,248,22,164,20, -198,86,95,28,28,248,22,175,15,23,195,2,10,28,248,22,155,7,23,195,2, -28,248,22,134,16,23,195,2,10,248,22,135,16,23,195,2,11,12,250,22,182, -11,2,7,2,50,23,197,2,28,28,23,195,2,28,28,248,22,175,15,23,196, -2,10,28,248,22,155,7,23,196,2,28,248,22,134,16,23,196,2,10,248,22, -135,16,23,196,2,11,248,22,134,16,23,196,2,11,10,12,250,22,182,11,2, -7,6,45,45,40,111,114,47,99,32,35,102,32,40,97,110,100,47,99,32,112, -97,116,104,45,115,116,114,105,110,103,63,32,114,101,108,97,116,105,118,101,45, -112,97,116,104,63,41,41,23,198,2,28,28,248,22,134,16,23,195,2,90,144, -42,11,89,146,42,39,11,248,22,132,16,23,198,2,249,22,171,9,194,2,51, -11,27,249,22,177,8,247,22,176,8,5,4,80,65,84,72,27,28,23,194,2, -249,80,143,43,44,249,22,167,8,23,198,1,7,63,9,86,94,23,194,1,9, -27,28,249,22,171,9,247,22,182,8,2,45,249,22,82,248,22,184,15,5,1, -46,23,196,1,23,194,1,28,248,22,90,23,194,2,11,27,249,22,129,16,248, -22,137,16,248,22,83,23,198,2,23,200,2,28,248,22,187,15,23,194,2,250, -2,88,201,202,195,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248,22, -90,23,194,2,11,27,249,22,129,16,248,22,137,16,248,22,83,23,198,2,23, -202,2,28,248,22,187,15,23,194,2,250,2,88,203,204,195,86,94,23,193,1, -27,248,22,164,20,23,196,1,28,248,22,90,23,194,2,11,27,249,22,129,16, -248,22,137,16,248,22,83,23,198,2,23,204,2,28,248,22,187,15,23,194,2, -250,2,88,205,206,195,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248, -22,90,23,194,2,11,27,249,22,129,16,248,22,137,16,248,22,83,197,205,28, -248,22,187,15,193,250,2,88,23,15,23,16,195,251,2,92,23,15,23,16,23, -17,248,22,164,20,198,27,248,22,137,16,23,196,1,28,248,22,187,15,193,250, -2,88,198,199,195,11,250,80,144,42,43,42,196,197,11,250,80,144,42,43,42, -196,11,11,32,97,88,148,8,36,42,58,11,2,52,222,33,99,0,8,35,114, -120,35,34,92,34,34,27,249,22,168,16,23,197,2,23,198,2,28,23,193,2, -86,94,23,196,1,27,248,22,104,23,195,2,27,27,248,22,113,23,197,1,27, -249,22,168,16,23,201,2,23,196,2,28,23,193,2,86,94,23,194,1,27,248, -22,104,23,195,2,27,250,2,97,202,23,204,1,248,22,113,23,199,1,27,28, -249,22,171,9,247,22,182,8,2,45,250,22,180,16,2,98,23,198,1,2,53, -194,28,249,22,152,8,194,2,53,249,22,96,202,195,249,22,82,248,22,184,15, -195,195,86,95,23,199,1,23,193,1,27,28,249,22,171,9,247,22,182,8,2, -45,250,22,180,16,2,98,23,198,1,2,53,194,28,249,22,152,8,194,2,53, -249,22,96,200,9,249,22,82,248,22,184,15,195,9,27,28,249,22,171,9,247, -22,182,8,2,45,250,22,180,16,2,98,23,198,1,2,53,194,28,249,22,152, -8,194,2,53,249,22,96,198,195,249,22,82,248,22,184,15,195,195,86,94,23, -193,1,27,28,249,22,171,9,247,22,182,8,2,45,250,22,180,16,2,98,23, -200,1,2,53,196,28,249,22,152,8,194,2,53,249,22,96,196,9,249,22,82, -248,22,184,15,195,9,86,95,28,28,248,22,144,8,194,10,248,22,155,7,194, -12,250,22,182,11,2,8,6,21,21,40,111,114,47,99,32,98,121,116,101,115, -63,32,115,116,114,105,110,103,63,41,196,28,28,248,22,91,195,249,22,4,22, -175,15,196,11,12,250,22,182,11,2,8,6,14,14,40,108,105,115,116,111,102, -32,112,97,116,104,63,41,197,250,2,97,197,195,28,248,22,155,7,197,248,22, -169,8,197,196,28,28,248,22,0,23,195,2,249,22,50,23,196,2,39,11,20, -13,144,80,144,39,46,40,26,29,80,144,8,29,47,40,249,22,33,11,80,144, -8,31,46,40,22,145,15,10,22,146,15,10,22,147,15,10,22,150,15,10,22, -149,15,11,22,151,15,10,22,148,15,10,22,152,15,10,22,153,15,10,22,154, -15,10,22,155,15,10,22,156,15,11,22,157,15,10,22,143,15,11,247,23,194, -1,250,22,182,11,2,9,2,54,23,197,1,86,94,28,28,248,22,175,15,23, -195,2,10,28,248,22,155,7,23,195,2,28,248,22,134,16,23,195,2,10,248, -22,135,16,23,195,2,11,12,250,22,182,11,23,196,2,2,50,23,197,2,28, -248,22,134,16,23,195,2,12,251,22,184,11,23,197,1,2,55,2,48,23,198, -1,86,94,28,28,248,22,175,15,23,195,2,10,28,248,22,155,7,23,195,2, -28,248,22,134,16,23,195,2,10,248,22,135,16,23,195,2,11,12,250,22,182, -11,23,196,2,2,50,23,197,2,28,248,22,134,16,23,195,2,12,251,22,184, -11,23,197,1,2,55,2,48,23,198,1,86,94,86,94,28,28,248,22,175,15, -23,195,2,10,28,248,22,155,7,23,195,2,28,248,22,134,16,23,195,2,10, -248,22,135,16,23,195,2,11,12,250,22,182,11,23,196,2,2,50,23,197,2, -28,248,22,134,16,23,195,2,86,94,23,194,1,12,251,22,184,11,23,197,2, -2,55,2,48,23,198,1,249,22,3,20,20,94,88,148,8,36,40,50,11,9, -223,2,33,103,23,195,1,23,197,1,28,28,248,22,0,23,195,2,249,22,50, -23,196,2,40,11,12,250,22,182,11,23,196,1,2,56,23,197,1,86,94,28, -28,248,22,175,15,23,194,2,10,28,248,22,155,7,23,194,2,28,248,22,134, -16,23,194,2,10,248,22,135,16,23,194,2,11,12,250,22,182,11,2,16,2, -50,23,196,2,28,248,22,134,16,23,194,2,12,251,22,184,11,2,16,2,55, -2,48,23,197,1,86,95,86,94,86,94,28,28,248,22,175,15,23,196,2,10, -28,248,22,155,7,23,196,2,28,248,22,134,16,23,196,2,10,248,22,135,16, -23,196,2,11,12,250,22,182,11,2,16,2,50,23,198,2,28,248,22,134,16, -23,196,2,12,251,22,184,11,2,16,2,55,2,48,23,199,2,249,22,3,32, -0,88,148,8,36,40,49,11,9,222,33,106,23,198,2,28,28,248,22,0,23, -195,2,249,22,50,23,196,2,40,11,12,250,22,182,11,2,16,2,56,23,197, -2,252,80,143,44,52,23,199,1,23,200,1,23,201,1,11,11,86,94,28,28, -248,22,175,15,23,194,2,10,28,248,22,155,7,23,194,2,28,248,22,134,16, -23,194,2,10,248,22,135,16,23,194,2,11,12,250,22,182,11,2,18,2,50, -23,196,2,28,248,22,134,16,23,194,2,12,251,22,184,11,2,18,2,55,2, -48,23,197,1,86,96,86,94,28,28,248,22,175,15,23,197,2,10,28,248,22, -155,7,23,197,2,28,248,22,134,16,23,197,2,10,248,22,135,16,23,197,2, -11,12,250,22,182,11,2,18,2,50,23,199,2,28,248,22,134,16,23,197,2, -12,251,22,184,11,2,18,2,55,2,48,23,200,2,86,94,86,94,28,28,248, -22,175,15,23,198,2,10,28,248,22,155,7,23,198,2,28,248,22,134,16,23, -198,2,10,248,22,135,16,23,198,2,11,12,250,22,182,11,2,18,2,50,23, -200,2,28,248,22,134,16,23,198,2,12,251,22,184,11,2,18,2,55,2,48, -23,201,2,249,22,3,32,0,88,148,8,36,40,49,11,9,222,33,108,23,200, -2,28,28,248,22,0,23,195,2,249,22,50,23,196,2,40,11,12,250,22,182, -11,2,18,2,56,23,197,2,252,80,143,44,52,23,199,1,23,202,1,23,203, -1,23,201,1,23,200,1,27,248,22,152,16,2,57,28,248,22,136,16,23,194, -2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11,89, -146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,49,43,42,248,22,152, -16,2,58,11,11,248,22,152,16,2,59,86,95,23,195,1,23,194,1,248,22, -139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, -152,16,2,58,23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11,249, -80,144,41,55,40,39,80,144,41,8,40,42,27,248,22,152,16,2,60,28,248, -22,136,16,23,194,2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2, -90,144,42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,49, -43,42,248,22,152,16,2,58,11,11,248,22,152,16,2,59,86,95,23,195,1, -23,194,1,248,22,139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144, -44,43,42,248,22,152,16,2,58,23,197,1,10,28,23,193,2,248,22,139,16, -23,194,1,11,249,80,144,41,55,40,40,80,144,41,8,41,42,27,20,13,144, -80,144,40,46,40,26,29,80,144,8,30,47,40,249,22,33,11,80,144,8,32, -46,40,22,145,15,10,22,146,15,10,22,147,15,10,22,150,15,10,22,149,15, -11,22,151,15,10,22,148,15,10,22,152,15,10,22,153,15,10,22,154,15,10, -22,155,15,10,22,156,15,11,22,157,15,10,22,143,15,11,247,22,150,6,28, -248,22,151,2,193,192,11,27,28,23,195,2,249,22,129,16,23,197,1,6,11, -11,99,111,110,102,105,103,46,114,107,116,100,86,94,23,195,1,11,27,28,23, -194,2,28,248,22,187,15,23,195,2,249,22,142,6,23,196,1,80,144,43,8, -42,42,11,11,28,192,192,21,17,1,0,250,22,160,2,23,196,1,2,61,247, -22,173,8,250,22,160,2,195,2,61,247,22,173,8,28,248,22,155,7,23,195, -2,27,248,22,183,15,23,196,1,28,248,22,136,16,23,194,2,192,249,22,137, -16,23,195,1,27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1, -247,22,153,16,28,248,22,144,8,23,195,2,27,248,22,184,15,23,196,1,28, -248,22,136,16,23,194,2,192,249,22,137,16,23,195,1,27,247,80,144,43,54, -42,28,23,193,2,192,86,94,23,193,1,247,22,153,16,28,248,22,175,15,23, -195,2,28,248,22,136,16,23,195,2,193,249,22,137,16,23,196,1,27,247,80, -144,42,54,42,28,23,193,2,192,86,94,23,193,1,247,22,153,16,193,27,248, -22,152,16,2,57,28,248,22,136,16,23,194,2,248,22,139,16,23,194,1,28, -248,22,135,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249, -22,137,16,250,80,144,49,43,42,248,22,152,16,2,58,11,11,248,22,152,16, -2,59,86,95,23,195,1,23,194,1,248,22,139,16,249,22,137,16,23,199,1, -23,196,1,27,250,80,144,44,43,42,248,22,152,16,2,58,23,197,1,10,28, -23,193,2,248,22,139,16,23,194,1,11,28,248,22,136,16,23,195,2,193,249, -22,137,16,23,196,1,27,249,80,144,44,55,40,39,80,144,44,8,43,42,28, -23,193,2,192,86,94,23,193,1,247,22,153,16,28,248,22,136,16,23,195,2, -248,22,139,16,23,195,1,28,248,22,135,16,23,195,2,90,144,42,11,89,146, -42,39,11,248,22,132,16,249,22,137,16,250,80,144,48,43,42,248,22,152,16, -2,58,11,11,248,22,152,16,2,59,86,95,23,195,1,23,194,1,248,22,139, -16,249,22,137,16,23,200,1,23,196,1,27,250,80,144,43,43,42,248,22,152, -16,2,58,23,198,1,10,28,23,193,2,248,22,139,16,23,194,1,11,28,248, -22,90,23,196,2,9,28,248,22,83,23,196,2,249,22,82,27,248,22,163,20, -23,199,2,28,248,22,155,7,23,194,2,27,248,22,183,15,23,195,1,28,248, -22,136,16,23,194,2,192,249,22,137,16,23,195,1,27,247,80,144,46,54,42, -28,23,193,2,192,86,94,23,193,1,247,22,153,16,28,248,22,144,8,23,194, -2,27,248,22,184,15,23,195,1,28,248,22,136,16,23,194,2,192,249,22,137, -16,23,195,1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1, -247,22,153,16,28,248,22,175,15,23,194,2,28,248,22,136,16,23,194,2,192, -249,22,137,16,23,195,1,27,247,80,144,45,54,42,28,23,193,2,192,86,94, -23,193,1,247,22,153,16,192,27,248,22,164,20,23,199,1,28,248,22,90,23, -194,2,9,28,248,22,83,23,194,2,249,22,82,248,80,144,45,60,42,248,22, -163,20,23,197,2,27,248,22,164,20,23,197,1,28,248,22,90,23,194,2,9, -28,248,22,83,23,194,2,249,22,82,248,80,144,48,60,42,248,22,163,20,23, -197,2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198,1,249,22, -96,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198,1, -249,22,96,23,199,2,27,248,22,164,20,23,197,1,28,248,22,90,23,194,2, -9,28,248,22,83,23,194,2,249,22,82,248,80,144,48,60,42,248,22,163,20, -23,197,2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198,1,249, -22,96,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198, -1,249,22,96,23,196,2,27,248,22,164,20,23,199,1,28,248,22,90,23,194, -2,9,28,248,22,83,23,194,2,249,22,82,248,80,144,45,60,42,248,22,163, -20,23,197,2,27,248,22,164,20,23,197,1,28,248,22,90,23,194,2,9,28, -248,22,83,23,194,2,249,22,82,248,80,144,48,60,42,248,22,163,20,23,197, -2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198,1,249,22,96, -23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198,1,249, -22,96,23,199,2,27,248,22,164,20,23,197,1,28,248,22,90,23,194,2,9, -28,248,22,83,23,194,2,249,22,82,248,80,144,48,60,42,248,22,163,20,23, -197,2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198,1,249,22, -96,23,202,2,249,80,144,49,8,44,42,23,204,1,248,22,164,20,23,198,1, -27,250,22,160,2,23,198,1,23,199,1,11,28,192,249,80,144,42,8,44,42, -198,194,196,27,248,22,152,16,2,60,28,248,22,136,16,23,194,2,248,22,139, -16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11,89,146,42,39,11, -248,22,132,16,249,22,137,16,250,80,144,49,43,42,248,22,152,16,2,58,11, -11,248,22,152,16,2,59,86,95,23,195,1,23,194,1,248,22,139,16,249,22, -137,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,152,16,2,58, -23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11,27,248,80,144,41, -58,42,249,80,144,43,55,40,40,80,144,43,8,45,42,27,27,250,22,160,2, -23,198,2,72,108,105,110,107,115,45,102,105,108,101,11,27,28,23,194,2,23, -194,1,86,94,23,194,1,249,22,129,16,27,250,22,160,2,23,202,2,71,115, -104,97,114,101,45,100,105,114,11,28,192,192,249,22,129,16,64,117,112,6,5, -5,115,104,97,114,101,2,62,28,248,22,155,7,23,194,2,27,248,22,183,15, -23,195,1,28,248,22,136,16,23,194,2,192,249,22,137,16,23,195,1,27,247, -80,144,47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,153,16,28,248, -22,144,8,23,194,2,27,248,22,184,15,23,195,1,28,248,22,136,16,23,194, -2,192,249,22,137,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192, -86,94,23,193,1,247,22,153,16,28,248,22,175,15,23,194,2,28,248,22,136, -16,23,194,2,192,249,22,137,16,23,195,1,27,247,80,144,46,54,42,28,23, -193,2,192,86,94,23,193,1,247,22,153,16,192,250,22,96,248,22,92,11,28, -247,22,160,16,28,247,22,161,16,248,22,92,250,22,129,16,248,22,152,16,2, -63,250,22,160,2,23,204,2,2,61,247,22,173,8,2,62,9,9,28,247,22, -161,16,250,80,144,47,8,23,42,23,200,1,1,18,108,105,110,107,115,45,115, -101,97,114,99,104,45,102,105,108,101,115,248,22,92,23,200,1,9,248,22,174, -13,23,194,1,249,22,16,80,144,41,8,26,41,28,248,22,130,13,23,197,2, -86,94,23,196,1,32,0,88,148,8,36,39,44,11,9,222,11,20,20,94,88, -148,8,36,39,46,11,9,223,3,33,126,23,196,1,32,128,2,88,148,39,40, -59,11,2,52,222,33,129,2,90,144,42,11,89,146,42,39,11,248,22,132,16, -23,197,1,86,95,23,195,1,23,194,1,28,248,22,175,15,23,194,2,28,248, -22,188,15,23,194,2,249,22,147,6,23,195,1,32,0,88,148,8,36,39,44, -11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,1,86, -95,23,195,1,23,194,1,28,248,22,175,15,23,194,2,28,248,22,188,15,23, -194,2,249,22,147,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11, -90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,1,86,95,23,195,1, -23,194,1,28,248,22,175,15,23,194,2,28,248,22,188,15,23,194,2,249,22, -147,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,90,144,42,11, -89,146,42,39,11,248,22,132,16,23,197,1,86,95,23,195,1,23,194,1,28, -248,22,175,15,23,194,2,28,248,22,188,15,23,194,2,249,22,147,6,23,195, -1,32,0,88,148,8,36,39,44,11,9,222,11,248,2,128,2,23,194,1,11, -11,11,11,32,130,2,88,148,8,36,40,58,11,2,52,222,33,131,2,27,249, -22,165,6,8,128,128,23,196,2,28,248,22,150,7,23,194,2,9,249,22,82, -23,195,1,27,249,22,165,6,8,128,128,23,199,2,28,248,22,150,7,23,194, -2,9,249,22,82,23,195,1,27,249,22,165,6,8,128,128,23,202,2,28,248, -22,150,7,23,194,2,9,249,22,82,23,195,1,27,249,22,165,6,8,128,128, -23,205,2,28,248,22,150,7,23,194,2,9,249,22,82,23,195,1,248,2,130, -2,23,206,1,27,249,22,165,6,8,128,128,23,196,2,28,248,22,144,8,23, -194,2,28,249,22,134,4,248,22,149,8,23,196,2,8,128,128,249,22,1,22, -156,8,249,22,82,23,197,1,27,249,22,165,6,8,128,128,23,201,2,28,248, -22,150,7,23,194,2,9,249,22,82,23,195,1,27,249,22,165,6,8,128,128, -23,204,2,28,248,22,150,7,23,194,2,9,249,22,82,23,195,1,27,249,22, -165,6,8,128,128,23,207,2,28,248,22,150,7,23,194,2,9,249,22,82,23, -195,1,27,249,22,165,6,8,128,128,23,210,2,28,248,22,150,7,23,194,2, -9,249,22,82,23,195,1,248,2,130,2,23,211,1,192,192,248,22,135,6,23, -194,1,20,13,144,80,144,40,8,28,40,80,144,40,8,46,42,27,28,249,22, -191,8,248,22,182,8,2,64,41,90,144,42,11,89,146,42,39,11,248,22,132, -16,23,198,2,86,95,23,195,1,23,194,1,28,248,22,175,15,23,194,2,28, -248,22,188,15,23,194,2,249,22,147,6,23,195,1,32,0,88,148,8,36,39, -44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,1, -86,95,23,195,1,23,194,1,28,248,22,175,15,23,194,2,28,248,22,188,15, -23,194,2,249,22,147,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222, -11,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,1,86,95,23,195, -1,23,194,1,28,248,22,175,15,23,194,2,28,248,22,188,15,23,194,2,249, -22,147,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,90,144,42, -11,89,146,42,39,11,248,22,132,16,23,197,1,86,95,23,195,1,23,194,1, -28,248,22,175,15,23,194,2,28,248,22,188,15,23,194,2,249,22,147,6,23, -195,1,32,0,88,148,8,36,39,44,11,9,222,11,248,2,128,2,23,194,1, -11,11,11,11,11,28,248,22,187,15,23,195,2,27,28,249,22,191,8,248,22, -182,8,2,64,41,249,22,147,6,23,197,2,32,0,88,148,8,36,39,44,11, -9,222,11,11,86,94,28,23,194,2,248,22,149,6,23,195,1,86,94,23,194, -1,12,249,22,82,27,248,22,190,5,23,199,1,250,22,46,22,37,88,148,39, -39,8,24,11,9,223,3,33,132,2,20,20,94,88,148,8,36,39,46,11,9, -223,3,33,133,2,23,196,1,194,249,22,82,11,194,28,28,23,195,2,28,248, -22,84,23,196,2,248,22,169,9,249,22,176,14,39,248,22,164,20,23,199,2, -11,11,194,86,94,23,195,1,249,22,14,20,20,94,88,148,8,32,39,61,16, -4,39,8,128,80,8,240,0,64,0,0,39,9,224,2,3,33,134,2,23,196, -1,80,144,41,8,26,41,27,248,22,169,9,194,28,192,192,248,22,169,9,248, -22,83,195,86,95,28,248,22,151,12,23,198,2,27,247,22,143,12,28,249,22, -133,12,23,195,2,2,65,251,22,139,12,23,197,1,2,65,250,22,139,8,6, -42,42,101,114,114,111,114,32,114,101,97,100,105,110,103,32,99,111,108,108,101, -99,116,105,111,110,32,108,105,110,107,115,32,102,105,108,101,32,126,115,58,32, -126,97,23,203,2,248,22,147,12,23,206,2,247,22,29,12,12,28,23,193,2, -250,22,158,2,80,144,45,8,25,41,23,198,1,249,22,82,23,198,1,21,17, -0,0,86,95,23,195,1,23,193,1,12,28,248,22,151,12,23,198,2,86,94, -23,197,1,248,23,195,1,247,22,140,2,196,88,148,39,40,58,8,240,0,0, -0,2,9,226,0,2,1,3,33,137,2,20,20,94,248,22,150,6,23,194,2, -28,248,22,150,7,248,22,150,6,23,195,1,12,248,22,178,11,6,30,30,101, -120,112,101,99,116,101,100,32,97,32,115,105,110,103,108,101,32,83,45,101,120, -112,114,101,115,115,105,111,110,248,22,135,6,23,194,1,28,248,22,91,193,28, -28,249,22,130,4,41,248,22,95,195,10,249,22,130,4,42,248,22,95,195,28, -28,248,22,155,7,248,22,83,194,10,28,249,22,171,9,2,66,248,22,163,20, -195,10,249,22,171,9,2,67,248,22,163,20,195,28,27,248,22,104,194,28,248, -22,175,15,193,10,28,248,22,155,7,193,28,248,22,134,16,193,10,248,22,135, -16,193,11,27,248,22,90,248,22,106,195,28,192,192,248,22,181,16,248,22,113, -195,11,11,11,11,28,248,22,188,15,249,22,129,16,23,196,2,23,198,2,27, -248,22,70,248,22,179,15,23,198,1,250,22,158,2,23,198,2,23,196,2,249, -22,82,23,199,1,250,22,160,2,23,203,1,23,201,1,9,12,250,22,158,2, -23,197,1,23,198,1,249,22,82,23,198,1,23,201,1,28,28,248,22,90,248, -22,106,23,197,2,10,249,22,172,16,248,22,113,23,198,2,247,22,173,8,27, -248,22,139,16,249,22,137,16,248,22,104,23,200,2,23,198,1,28,249,22,171, -9,248,22,163,20,23,199,2,2,67,86,94,23,196,1,249,22,3,20,20,94, -88,148,8,36,40,56,11,9,224,3,2,33,142,2,23,196,1,248,22,142,16, -23,196,1,28,249,22,171,9,248,22,163,20,23,199,2,2,66,86,94,23,196, -1,86,94,28,250,22,160,2,23,197,2,11,11,12,250,22,158,2,23,197,2, -11,9,249,22,166,2,23,196,2,20,20,95,88,148,8,36,41,53,11,9,224, -3,2,33,143,2,23,195,1,23,196,1,27,248,22,70,248,22,163,20,23,199, -1,250,22,158,2,23,198,2,23,196,2,249,22,82,248,22,131,2,23,200,1, -250,22,160,2,23,203,1,23,201,1,9,12,250,22,158,2,23,196,1,23,197, -1,248,22,97,23,199,1,27,28,28,23,194,2,248,22,169,9,248,22,83,23, -196,2,10,9,27,249,22,190,5,23,198,2,68,98,105,110,97,114,121,250,22, -46,22,37,88,148,8,36,39,47,11,9,223,3,33,139,2,20,20,94,88,148, -8,36,39,46,11,9,223,3,33,140,2,23,196,1,86,94,28,28,248,22,91, -23,194,2,249,22,4,32,0,88,148,8,36,40,48,11,9,222,33,141,2,23, -195,2,11,12,248,22,178,11,6,18,18,105,108,108,45,102,111,114,109,101,100, -32,99,111,110,116,101,110,116,27,247,22,140,2,27,90,144,42,11,89,146,42, -39,11,248,22,132,16,23,201,2,192,86,96,249,22,3,20,20,94,88,148,8, -36,40,57,11,9,224,2,3,33,144,2,23,195,1,23,197,1,249,22,166,2, -195,88,148,8,36,41,51,11,9,223,3,33,145,2,250,22,158,2,80,144,47, -8,25,41,23,200,1,249,22,82,23,201,1,198,193,20,13,144,80,144,40,8, -28,40,250,80,144,43,8,47,42,23,198,2,23,196,2,11,27,250,22,160,2, -80,144,44,8,25,41,23,197,2,21,143,11,17,0,0,27,248,22,83,23,195, -2,27,249,80,144,45,8,27,42,23,198,2,23,196,2,28,249,22,173,9,23, -195,2,23,196,1,248,22,164,20,195,86,94,23,195,1,20,13,144,80,144,43, -8,28,40,250,80,144,46,8,47,42,23,201,1,23,199,2,23,196,2,27,20, -20,95,88,148,8,36,39,55,8,240,0,0,0,2,9,225,5,4,1,33,146, -2,23,194,1,23,197,1,28,249,22,50,23,195,2,39,20,13,144,80,144,44, -46,40,26,29,80,144,8,34,47,40,249,22,33,11,80,144,8,36,46,40,22, -145,15,10,22,146,15,10,22,147,15,10,22,150,15,10,22,149,15,11,22,151, -15,10,22,148,15,10,22,152,15,10,22,153,15,10,22,154,15,10,22,155,15, -10,22,156,15,11,22,157,15,10,22,143,15,11,247,23,193,1,250,22,182,11, -2,9,2,54,23,196,1,248,22,8,20,20,94,88,148,39,40,8,43,16,4, -8,128,6,8,128,104,8,240,0,128,0,0,39,9,224,1,2,33,147,2,23, -195,1,0,7,35,114,120,34,47,43,34,28,248,22,155,7,23,195,2,27,249, -22,170,16,2,149,2,23,197,2,28,23,193,2,28,249,22,130,4,248,22,103, -23,196,2,248,22,184,3,248,22,158,7,23,199,2,249,22,7,250,22,177,7, -23,200,1,39,248,22,103,23,199,1,23,198,1,249,22,7,250,22,177,7,23, -200,2,39,248,22,103,23,199,2,249,22,82,249,22,177,7,23,201,1,248,22, -105,23,200,1,23,200,1,249,22,7,23,197,1,23,198,1,90,144,42,11,89, -146,42,39,11,248,22,132,16,23,198,1,86,94,23,195,1,28,249,22,171,9, -23,195,2,2,51,86,94,23,193,1,249,22,7,23,196,1,23,200,1,27,249, -22,82,23,197,1,23,201,1,28,248,22,155,7,23,195,2,27,249,22,170,16, -2,149,2,23,197,2,28,23,193,2,28,249,22,130,4,248,22,103,23,196,2, -248,22,184,3,248,22,158,7,23,199,2,249,22,7,250,22,177,7,23,200,1, -39,248,22,103,23,199,1,23,196,1,249,22,7,250,22,177,7,23,200,2,39, -248,22,103,23,199,2,249,22,82,249,22,177,7,23,201,1,248,22,105,23,200, -1,23,198,1,249,22,7,23,197,1,23,196,1,90,144,42,11,89,146,42,39, -11,248,22,132,16,23,198,1,86,94,23,195,1,28,249,22,171,9,23,195,2, -2,51,86,94,23,193,1,249,22,7,23,196,1,23,198,1,249,80,144,48,8, -31,42,194,249,22,82,197,199,28,248,22,90,23,196,2,9,28,248,22,83,23, -196,2,28,248,22,151,2,248,22,163,20,23,197,2,250,22,96,249,22,2,22, -131,2,250,22,160,2,248,22,163,20,23,204,2,23,202,2,9,250,22,160,2, -248,22,163,20,23,202,2,11,9,27,248,22,164,20,23,200,1,28,248,22,90, -23,194,2,9,28,248,22,83,23,194,2,28,248,22,151,2,248,22,163,20,23, -195,2,250,22,96,249,22,2,22,131,2,250,22,160,2,248,22,163,20,23,202, -2,23,206,2,9,250,22,160,2,248,22,163,20,23,200,2,11,9,249,80,144, -48,8,48,42,23,203,1,248,22,164,20,23,199,1,27,248,80,144,45,8,30, -42,248,22,163,20,23,196,2,250,22,96,250,22,160,2,23,199,2,23,205,2, -9,250,22,160,2,23,199,1,11,9,249,80,144,49,8,48,42,23,204,1,248, -22,164,20,23,200,1,249,22,96,247,22,156,16,249,80,144,47,8,48,42,23, -202,1,248,22,164,20,23,198,1,27,248,80,144,41,8,30,42,248,22,163,20, -23,198,2,250,22,96,250,22,160,2,23,199,2,23,201,2,9,250,22,160,2, -23,199,1,11,9,27,248,22,164,20,23,201,1,28,248,22,90,23,194,2,9, -28,248,22,83,23,194,2,28,248,22,151,2,248,22,163,20,23,195,2,250,22, -96,249,22,2,22,131,2,250,22,160,2,248,22,163,20,23,202,2,23,207,2, -9,250,22,160,2,248,22,163,20,23,200,2,11,9,249,80,144,49,8,48,42, -23,204,1,248,22,164,20,23,199,1,27,248,80,144,46,8,30,42,248,22,163, -20,23,196,2,250,22,96,250,22,160,2,23,199,2,23,206,2,9,250,22,160, -2,23,199,1,11,9,249,80,144,50,8,48,42,23,205,1,248,22,164,20,23, -200,1,249,22,96,247,22,156,16,249,80,144,48,8,48,42,23,203,1,248,22, -164,20,23,198,1,249,22,96,247,22,156,16,27,248,22,164,20,23,199,1,28, -248,22,90,23,194,2,9,28,248,22,83,23,194,2,28,248,22,151,2,248,22, -163,20,23,195,2,250,22,96,249,22,2,22,131,2,250,22,160,2,248,22,163, -20,23,202,2,23,205,2,9,250,22,160,2,248,22,163,20,23,200,2,11,9, -249,80,144,47,8,48,42,23,202,1,248,22,164,20,23,199,1,27,248,80,144, -44,8,30,42,248,22,163,20,23,196,2,250,22,96,250,22,160,2,23,199,2, -23,204,2,9,250,22,160,2,23,199,1,11,9,249,80,144,48,8,48,42,23, -203,1,248,22,164,20,23,200,1,249,22,96,247,22,156,16,249,80,144,46,8, -48,42,23,201,1,248,22,164,20,23,198,1,32,152,2,88,148,8,36,40,50, -11,2,52,222,33,153,2,28,248,22,90,248,22,84,23,195,2,248,22,92,27, -248,22,163,20,195,28,248,22,175,15,193,248,22,179,15,193,192,250,22,93,27, -248,22,163,20,23,198,2,28,248,22,175,15,193,248,22,179,15,193,192,2,69, -248,2,152,2,248,22,164,20,23,198,1,250,22,139,8,6,7,7,10,32,126, -97,32,126,97,6,1,1,32,23,196,1,249,22,139,8,6,6,6,10,32,32, -32,126,97,248,22,134,2,23,196,1,32,156,2,88,148,39,41,51,11,68,102, -105,108,116,101,114,222,33,157,2,28,248,22,90,23,195,2,9,28,248,23,194, -2,248,22,83,23,196,2,249,22,82,248,22,163,20,23,197,2,249,2,156,2, -23,197,1,248,22,164,20,23,199,1,249,2,156,2,23,195,1,248,22,164,20, -23,197,1,28,248,22,90,23,201,2,86,95,23,200,1,23,199,1,28,23,201, -2,28,197,249,22,129,16,202,199,200,27,28,248,22,90,23,198,2,2,68,249, -22,1,22,178,7,248,2,152,2,23,200,2,248,23,199,1,251,22,139,8,6, -70,70,99,111,108,108,101,99,116,105,111,110,32,110,111,116,32,102,111,117,110, -100,10,32,32,99,111,108,108,101,99,116,105,111,110,58,32,126,115,10,32,32, -105,110,32,99,111,108,108,101,99,116,105,111,110,32,100,105,114,101,99,116,111, -114,105,101,115,58,126,97,126,97,28,248,22,90,23,203,1,28,248,22,175,15, -23,202,2,248,22,179,15,23,202,1,23,201,1,250,22,178,7,28,248,22,175, -15,23,205,2,248,22,179,15,23,205,1,23,204,1,2,69,23,201,2,249,22, -1,22,178,7,249,22,2,32,0,88,148,8,36,40,48,11,9,222,33,154,2, -27,248,22,95,23,206,2,27,248,22,95,247,22,156,16,28,249,22,131,4,249, -22,186,3,23,198,2,23,197,2,44,23,206,2,249,22,96,247,22,156,16,248, -22,92,249,22,139,8,6,50,50,46,46,46,32,91,126,97,32,97,100,100,105, -116,105,111,110,97,108,32,108,105,110,107,101,100,32,97,110,100,32,112,97,99, -107,97,103,101,32,100,105,114,101,99,116,111,114,105,101,115,93,249,22,186,3, -23,201,1,23,200,1,28,249,22,5,22,133,2,23,202,2,250,22,139,8,6, -49,49,10,32,32,32,115,117,98,45,99,111,108,108,101,99,116,105,111,110,58, -32,126,115,10,32,32,105,110,32,112,97,114,101,110,116,32,100,105,114,101,99, -116,111,114,105,101,115,58,126,97,23,201,1,249,22,1,22,178,7,249,22,2, -32,0,88,148,8,36,40,48,11,9,222,33,155,2,249,2,156,2,22,133,2, -23,209,1,86,95,23,200,1,23,198,1,2,68,27,248,22,83,23,202,2,27, -28,248,22,175,15,23,195,2,249,22,129,16,23,196,1,23,199,2,248,22,134, -2,23,195,1,28,28,248,22,175,15,248,22,163,20,23,204,2,248,22,188,15, -23,194,2,10,27,250,22,1,22,129,16,23,197,1,23,202,2,28,28,248,22, -90,23,200,2,10,248,22,188,15,23,194,2,28,23,201,2,28,28,250,80,144, -45,8,32,42,195,203,204,10,27,28,248,22,175,15,202,248,22,179,15,202,201, -19,248,22,158,7,23,195,2,27,28,249,22,134,4,23,196,4,43,28,249,22, -161,7,6,4,4,46,114,107,116,249,22,177,7,23,199,2,249,22,186,3,23, -200,4,43,249,22,178,7,250,22,177,7,23,200,1,39,249,22,186,3,23,201, -4,43,6,3,3,46,115,115,86,94,23,195,1,11,11,28,23,193,2,250,80, -144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249,22,129,16,194,202, -192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16,23,17,248,22,164, -20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8,49,42,204,205,206, -23,15,23,16,23,17,248,22,164,20,23,19,23,19,26,8,80,144,49,8,49, -42,203,204,205,206,23,15,23,16,248,22,164,20,23,18,23,18,90,144,41,11, -89,146,41,39,11,249,80,144,43,8,31,42,23,199,1,23,200,1,27,248,22, -70,28,248,22,175,15,195,248,22,179,15,195,194,27,27,247,22,157,16,28,248, -22,90,23,194,2,9,28,248,22,83,23,194,2,28,248,22,151,2,248,22,163, -20,23,195,2,250,22,96,249,22,2,22,131,2,250,22,160,2,248,22,163,20, -23,202,2,23,203,2,9,250,22,160,2,248,22,163,20,23,200,2,11,9,249, -80,144,49,8,48,42,23,200,1,248,22,164,20,23,199,1,27,248,80,144,46, -8,30,42,248,22,163,20,23,196,2,250,22,96,250,22,160,2,23,199,2,23, -202,2,9,250,22,160,2,23,199,1,11,9,249,80,144,50,8,48,42,23,201, -1,248,22,164,20,23,200,1,249,22,96,247,22,156,16,249,80,144,48,8,48, -42,23,199,1,248,22,164,20,23,198,1,26,8,80,144,51,8,49,42,200,202, -203,205,23,16,23,17,200,11,32,160,2,88,148,8,36,42,59,11,2,52,222, -33,161,2,28,248,22,135,4,23,196,2,86,94,23,195,1,19,248,22,149,8, -23,195,2,19,248,22,149,8,23,196,2,249,22,185,15,27,251,22,156,8,250, -22,155,8,23,205,2,39,23,204,4,2,53,249,22,155,8,23,204,1,23,202, -4,2,70,28,248,22,135,4,248,22,149,8,23,195,2,86,94,23,193,1,251, -22,184,11,2,39,2,71,2,72,202,192,28,248,22,176,15,198,248,22,177,15, -198,247,22,178,15,2,2,27,248,22,184,3,23,197,1,28,249,22,171,9,8, -46,249,22,150,8,23,198,2,23,197,2,27,248,22,183,3,23,195,2,249,22, -185,15,27,251,22,156,8,250,22,155,8,23,205,2,39,23,204,1,2,73,249, -22,155,8,23,204,1,23,202,1,2,70,28,248,22,135,4,248,22,149,8,23, -195,2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,202,192,28,248, -22,176,15,198,248,22,177,15,198,247,22,178,15,250,2,160,2,196,197,195,248, -22,187,15,27,250,22,129,16,23,200,1,23,202,1,23,199,1,28,249,22,171, -9,23,197,2,66,115,97,109,101,192,28,248,22,134,16,23,196,2,249,22,129, -16,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249,22,5,20,20,96, -88,148,39,40,54,47,9,226,5,4,2,6,33,162,2,23,199,1,23,195,1, -23,197,1,23,196,1,27,248,22,187,15,249,22,129,16,23,198,2,23,199,2, -28,23,193,2,192,86,94,23,193,1,28,23,197,1,27,90,144,41,11,89,146, -41,39,11,250,80,144,46,8,34,42,23,202,2,2,70,2,39,27,248,22,181, -15,23,196,1,27,250,2,160,2,23,197,2,23,204,1,248,22,149,8,23,198, -1,28,248,22,176,15,195,249,22,129,16,196,194,192,27,247,22,158,16,249,22, -5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3,33,163,2,23,196, -1,23,195,1,23,199,1,247,22,159,16,11,86,95,28,28,248,22,176,15,23, -194,2,10,28,248,22,175,15,23,194,2,10,28,248,22,155,7,23,194,2,28, -248,22,134,16,23,194,2,10,248,22,135,16,23,194,2,11,12,252,22,182,11, -23,200,2,2,44,39,23,198,2,23,199,2,28,28,248,22,155,7,23,195,2, -10,248,22,144,8,23,195,2,86,94,23,194,1,12,252,22,182,11,23,200,2, -2,74,40,23,198,2,23,199,1,90,144,42,11,89,146,42,39,11,248,22,132, -16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86,95,23,198,1,23, -196,1,12,250,22,185,11,23,201,1,2,75,23,199,1,249,22,7,23,195,1, -23,196,1,32,166,2,88,148,8,36,46,61,11,2,76,222,33,167,2,249,22, -185,15,27,251,22,156,8,250,22,155,8,23,203,2,39,23,207,1,23,205,1, -249,23,203,1,23,202,1,23,208,1,28,248,22,155,7,23,204,2,249,22,170, -8,23,205,1,8,63,23,203,1,28,248,22,135,4,248,22,149,8,23,195,2, -86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,201,192,28,248,22,176, -15,197,248,22,177,15,197,247,22,178,15,32,168,2,88,148,8,36,45,8,24, -11,2,52,222,33,169,2,28,248,22,135,4,23,199,2,86,95,23,198,1,23, -194,1,19,248,22,149,8,23,195,2,19,248,22,149,8,23,196,2,249,22,185, -15,27,251,22,156,8,250,22,155,8,23,205,2,39,23,204,4,2,53,249,23, -206,1,23,204,1,23,202,4,28,248,22,155,7,23,207,2,249,22,170,8,23, -208,1,8,63,23,206,1,28,248,22,135,4,248,22,149,8,23,195,2,86,94, -23,193,1,251,22,184,11,2,39,2,71,2,72,204,192,28,248,22,176,15,200, -248,22,177,15,200,247,22,178,15,2,2,27,248,22,184,3,23,200,1,28,249, -22,171,9,8,46,249,22,150,8,23,198,2,23,197,2,27,248,22,183,3,23, -195,2,249,22,185,15,27,251,22,156,8,250,22,155,8,23,205,2,39,23,204, -1,23,203,1,249,23,206,1,23,204,1,23,202,1,28,248,22,155,7,23,207, -2,249,22,170,8,23,208,1,8,63,23,206,1,28,248,22,135,4,248,22,149, -8,23,195,2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,204,192, -28,248,22,176,15,200,248,22,177,15,200,247,22,178,15,28,248,22,135,4,23, -194,2,86,95,23,195,1,23,193,1,19,248,22,149,8,23,196,2,19,248,22, -149,8,23,197,2,249,22,185,15,27,251,22,156,8,250,22,155,8,23,206,2, -39,23,204,4,2,53,249,23,207,1,23,205,1,23,202,4,28,248,22,155,7, -23,208,2,249,22,170,8,23,209,1,8,63,23,207,1,28,248,22,135,4,248, -22,149,8,23,195,2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72, -205,192,28,248,22,176,15,201,248,22,177,15,201,247,22,178,15,2,2,27,248, -22,184,3,23,195,1,28,249,22,171,9,8,46,249,22,150,8,23,199,2,23, -197,2,27,248,22,183,3,23,195,2,249,22,185,15,27,251,22,156,8,250,22, -155,8,23,206,2,39,23,204,1,23,204,1,249,23,207,1,23,205,1,23,202, -1,28,248,22,155,7,23,208,2,249,22,170,8,23,209,1,8,63,23,207,1, -28,248,22,135,4,248,22,149,8,23,195,2,86,94,23,193,1,251,22,184,11, -2,39,2,71,2,72,205,192,28,248,22,176,15,201,248,22,177,15,201,247,22, -178,15,28,248,22,135,4,193,254,2,166,2,201,203,204,205,248,22,149,8,202, -2,53,248,22,149,8,202,27,248,22,184,3,194,28,249,22,171,9,8,46,249, -22,150,8,199,196,254,2,166,2,202,204,205,206,199,203,248,22,183,3,200,253, -2,168,2,201,202,203,204,205,198,90,144,41,11,89,146,41,39,11,86,95,28, -28,248,22,176,15,23,199,2,10,28,248,22,175,15,23,199,2,10,28,248,22, -155,7,23,199,2,28,248,22,134,16,23,199,2,10,248,22,135,16,23,199,2, -11,12,252,22,182,11,23,200,2,2,44,39,23,203,2,23,204,2,28,28,248, -22,155,7,23,200,2,10,248,22,144,8,23,200,2,12,252,22,182,11,23,200, -2,2,74,40,23,203,2,23,204,2,90,144,42,11,89,146,42,39,11,248,22, -132,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250,22,185,11,23,201, -1,2,75,23,204,2,249,22,7,194,195,27,248,22,181,15,23,196,1,27,19, -248,22,149,8,23,196,2,28,248,22,135,4,23,194,4,86,94,23,199,1,19, -248,22,149,8,23,197,2,19,248,22,149,8,23,198,2,249,22,185,15,27,251, -22,156,8,250,22,155,8,23,207,2,39,23,204,4,2,53,249,23,211,1,23, -206,1,23,202,4,28,248,22,155,7,23,212,2,249,22,170,8,23,213,1,8, -63,23,211,1,28,248,22,135,4,248,22,149,8,23,195,2,86,94,23,193,1, -251,22,184,11,2,39,2,71,2,72,23,17,192,28,248,22,176,15,205,248,22, -177,15,205,247,22,178,15,2,2,27,248,22,184,3,23,195,4,28,249,22,171, -9,8,46,249,22,150,8,23,200,2,23,197,2,27,248,22,183,3,23,195,2, -249,22,185,15,27,251,22,156,8,250,22,155,8,23,207,2,39,23,204,1,23, -208,1,249,23,211,1,23,206,1,23,202,1,28,248,22,155,7,23,212,2,249, -22,170,8,23,213,1,8,63,23,211,1,28,248,22,135,4,248,22,149,8,23, -195,2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,23,17,192,28, -248,22,176,15,205,248,22,177,15,205,247,22,178,15,28,248,22,135,4,23,194, -2,86,95,23,200,1,23,193,1,254,2,166,2,23,203,2,23,208,1,23,209, -1,23,210,1,248,22,149,8,23,204,2,2,53,248,22,149,8,23,204,1,27, -248,22,184,3,23,195,1,28,249,22,171,9,8,46,249,22,150,8,23,201,2, -23,197,2,254,2,166,2,23,204,1,23,209,1,23,210,1,23,211,1,23,200, -2,23,208,1,248,22,183,3,23,201,1,253,2,168,2,23,203,1,23,207,1, -23,208,1,23,209,1,23,210,1,23,199,1,2,28,248,22,176,15,195,249,22, -129,16,196,194,192,32,171,2,88,148,8,36,43,61,11,2,52,222,33,172,2, -28,248,22,135,4,23,197,2,86,94,23,196,1,19,248,22,149,8,23,195,2, -35,248,22,149,8,23,196,2,249,22,185,15,27,251,22,156,8,250,22,155,8, -23,205,1,39,23,204,4,2,53,2,53,28,248,22,155,7,23,205,2,249,22, -170,8,23,206,1,8,63,23,204,1,28,248,22,135,4,248,22,149,8,23,195, -2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,202,192,28,248,22, -176,15,198,248,22,177,15,198,247,22,178,15,2,27,248,22,184,3,23,198,1, -28,249,22,171,9,8,46,249,22,150,8,23,198,2,23,197,2,35,248,22,183, -3,23,195,2,249,22,185,15,27,251,22,156,8,250,22,155,8,23,205,1,39, -23,204,1,2,53,2,53,28,248,22,155,7,23,205,2,249,22,170,8,23,206, -1,8,63,23,204,1,28,248,22,135,4,248,22,149,8,23,195,2,86,94,23, -193,1,251,22,184,11,2,39,2,71,2,72,202,192,28,248,22,176,15,198,248, -22,177,15,198,247,22,178,15,28,248,22,135,4,23,194,2,86,94,23,193,1, -19,248,22,149,8,23,196,2,35,248,22,149,8,23,197,2,249,22,185,15,27, -251,22,156,8,250,22,155,8,23,206,1,39,23,204,4,2,53,2,53,28,248, -22,155,7,23,206,2,249,22,170,8,23,207,1,8,63,23,205,1,28,248,22, -135,4,248,22,149,8,23,195,2,86,94,23,193,1,251,22,184,11,2,39,2, -71,2,72,203,192,28,248,22,176,15,199,248,22,177,15,199,247,22,178,15,2, -27,248,22,184,3,23,195,1,28,249,22,171,9,8,46,249,22,150,8,23,199, -2,23,197,2,35,248,22,183,3,23,195,2,249,22,185,15,27,251,22,156,8, -250,22,155,8,23,206,1,39,23,204,1,2,53,2,53,28,248,22,155,7,23, -206,2,249,22,170,8,23,207,1,8,63,23,205,1,28,248,22,135,4,248,22, -149,8,23,195,2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,203, -192,28,248,22,176,15,199,248,22,177,15,199,247,22,178,15,251,2,171,2,198, -199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,176,15,23, -196,2,10,28,248,22,175,15,23,196,2,10,28,248,22,155,7,23,196,2,28, -248,22,134,16,23,196,2,10,248,22,135,16,23,196,2,11,12,252,22,182,11, -2,39,2,44,39,23,200,2,23,201,2,28,28,248,22,155,7,23,197,2,10, -248,22,144,8,23,197,2,12,252,22,182,11,2,39,2,74,40,23,200,2,23, -201,2,90,144,42,11,89,146,42,39,11,248,22,132,16,23,199,2,86,94,23, -195,1,86,94,28,192,12,250,22,185,11,2,39,2,75,23,201,2,249,22,7, -194,195,27,248,22,181,15,23,196,1,27,251,2,171,2,23,198,2,23,201,1, -23,202,1,248,22,149,8,23,199,1,28,248,22,176,15,195,249,22,129,16,196, -194,192,2,53,252,80,144,44,8,35,42,2,39,2,53,32,0,88,148,8,36, -41,46,11,9,222,33,174,2,198,199,32,176,2,88,148,8,36,43,60,11,2, -52,222,33,179,2,32,177,2,88,148,8,36,45,60,11,2,76,222,33,178,2, -249,22,185,15,27,251,22,156,8,250,22,155,8,23,203,2,39,23,206,1,23, -204,1,249,22,155,8,23,202,1,23,207,1,28,248,22,155,7,23,203,2,249, -22,170,8,23,204,1,8,63,23,202,1,28,248,22,135,4,248,22,149,8,23, -195,2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,200,192,28,248, -22,176,15,196,248,22,177,15,196,247,22,178,15,28,248,22,135,4,23,197,2, -86,94,23,196,1,19,248,22,149,8,23,195,2,19,248,22,149,8,23,196,2, -249,22,185,15,27,251,22,156,8,250,22,155,8,23,205,2,39,23,204,4,2, -53,249,22,155,8,23,204,1,23,202,4,28,248,22,155,7,23,205,2,249,22, -170,8,23,206,1,8,63,23,204,1,28,248,22,135,4,248,22,149,8,23,195, -2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72,202,192,28,248,22, -176,15,198,248,22,177,15,198,247,22,178,15,2,2,27,248,22,184,3,23,198, -1,28,249,22,171,9,8,46,249,22,150,8,23,198,2,23,197,2,27,248,22, -183,3,23,195,2,249,22,185,15,27,251,22,156,8,250,22,155,8,23,205,2, -39,23,204,1,2,73,249,22,155,8,23,204,1,23,202,1,28,248,22,155,7, -23,205,2,249,22,170,8,23,206,1,8,63,23,204,1,28,248,22,135,4,248, -22,149,8,23,195,2,86,94,23,193,1,251,22,184,11,2,39,2,71,2,72, -202,192,28,248,22,176,15,198,248,22,177,15,198,247,22,178,15,28,248,22,135, -4,193,253,2,177,2,199,200,201,248,22,149,8,200,2,53,248,22,149,8,200, -27,248,22,184,3,194,28,249,22,171,9,8,46,249,22,150,8,198,196,253,2, -177,2,200,201,202,198,2,73,248,22,183,3,199,251,2,176,2,198,199,200,196, -90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,176,15,23,196,2,10, -28,248,22,175,15,23,196,2,10,28,248,22,155,7,23,196,2,28,248,22,134, -16,23,196,2,10,248,22,135,16,23,196,2,11,12,252,22,182,11,2,39,2, -44,39,23,200,2,23,201,2,28,28,248,22,155,7,23,197,2,10,248,22,144, -8,23,197,2,12,252,22,182,11,2,39,2,74,40,23,200,2,23,201,2,90, -144,42,11,89,146,42,39,11,248,22,132,16,23,199,2,86,94,23,195,1,86, -94,28,192,12,250,22,185,11,2,39,2,75,23,201,2,249,22,7,194,195,27, -248,22,181,15,23,196,1,27,251,2,176,2,23,198,2,23,201,1,23,202,1, -248,22,149,8,23,199,1,28,248,22,176,15,195,249,22,129,16,196,194,192,252, -80,144,44,8,35,42,2,39,2,73,22,155,8,198,199,249,247,22,178,5,23, -195,1,11,249,247,22,178,5,194,11,28,248,22,90,23,195,2,9,27,27,248, -22,83,23,197,2,28,248,22,136,16,23,194,2,248,22,139,16,23,194,1,28, -248,22,135,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249, -22,137,16,250,80,144,50,43,42,248,22,152,16,2,58,11,11,248,22,152,16, -2,59,86,95,23,195,1,23,194,1,248,22,139,16,249,22,137,16,23,199,1, -23,196,1,27,250,80,144,45,43,42,248,22,152,16,2,58,23,197,1,10,28, -23,193,2,248,22,139,16,23,194,1,11,28,23,193,2,249,22,82,248,22,139, -16,249,22,137,16,23,198,1,247,22,153,16,27,248,22,164,20,23,199,1,28, -248,22,90,23,194,2,9,27,248,80,144,45,56,42,248,22,83,23,196,2,28, -23,193,2,249,22,82,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16, -248,80,144,47,8,50,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80, -144,45,8,50,42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164, -20,23,197,1,28,248,22,90,23,194,2,9,27,248,80,144,43,56,42,248,22, -83,23,196,2,28,23,193,2,249,22,82,248,22,139,16,249,22,137,16,23,198, -1,247,22,153,16,248,80,144,45,8,50,42,248,22,164,20,23,198,1,86,94, -23,193,1,248,80,144,43,8,50,42,248,22,164,20,23,196,1,28,248,22,90, -23,195,2,9,27,27,248,22,83,23,197,2,28,248,22,136,16,23,194,2,248, -22,139,16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11,89,146,42, -39,11,248,22,132,16,249,22,137,16,250,80,144,50,43,42,248,22,152,16,2, -58,11,11,248,22,152,16,2,59,86,95,23,195,1,23,194,1,248,22,139,16, -249,22,137,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,152,16, -2,58,23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11,28,23,193, -2,249,22,82,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,27,248, -22,164,20,23,199,1,28,248,22,90,23,194,2,9,27,248,80,144,45,56,42, -248,22,83,23,196,2,28,23,193,2,249,22,82,248,22,139,16,249,22,137,16, -23,198,1,247,22,153,16,248,80,144,47,8,51,42,248,22,164,20,23,198,1, -86,94,23,193,1,248,80,144,45,8,51,42,248,22,164,20,23,196,1,86,94, -23,193,1,27,248,22,164,20,23,197,1,28,248,22,90,23,194,2,9,27,248, -80,144,43,56,42,248,22,83,23,196,2,28,23,193,2,249,22,82,248,22,139, -16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,45,8,51,42,248,22, -164,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42,248,22,164,20, -23,196,1,27,248,22,152,16,2,60,28,248,22,136,16,23,194,2,248,22,139, -16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11,89,146,42,39,11, -248,22,132,16,249,22,137,16,250,80,144,49,43,42,248,22,152,16,2,58,11, -11,248,22,152,16,2,59,86,95,23,195,1,23,194,1,248,22,139,16,249,22, -137,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,152,16,2,58, -23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11,28,248,22,90,23, -195,2,9,27,27,248,22,83,23,197,2,28,248,22,136,16,23,194,2,248,22, -139,16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11,89,146,42,39, -11,248,22,132,16,249,22,137,16,250,80,144,50,43,42,248,22,152,16,2,58, -11,11,248,22,152,16,2,59,86,95,23,195,1,23,194,1,248,22,139,16,249, -22,137,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,152,16,2, -58,23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11,28,23,193,2, -249,22,82,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,27,248,22, -164,20,23,199,1,28,248,22,90,23,194,2,9,27,27,248,22,83,23,196,2, -28,248,22,136,16,23,194,2,248,22,139,16,23,194,1,28,248,22,135,16,23, -194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250,80, -144,54,43,42,248,22,152,16,2,58,11,11,248,22,152,16,2,59,86,95,23, -195,1,23,194,1,248,22,139,16,249,22,137,16,23,199,1,23,196,1,27,250, -80,144,49,43,42,248,22,152,16,2,58,23,197,1,10,28,23,193,2,248,22, -139,16,23,194,1,11,28,23,193,2,249,22,82,248,22,139,16,249,22,137,16, -23,198,1,247,22,153,16,27,248,22,164,20,23,198,1,28,248,22,90,23,194, -2,9,27,248,80,144,49,56,42,248,22,83,23,196,2,28,23,193,2,249,22, -82,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,51,8, -53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144,49,8,53,42, -248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164,20,23,196,1,28, -248,22,90,23,194,2,9,27,248,80,144,47,56,42,248,22,83,23,196,2,28, -23,193,2,249,22,82,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16, -248,80,144,49,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80, -144,47,8,53,42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164, -20,23,197,1,28,248,22,90,23,194,2,9,27,27,248,22,83,23,196,2,28, -248,22,136,16,23,194,2,248,22,139,16,23,194,1,28,248,22,135,16,23,194, -2,90,144,42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250,80,144, -52,43,42,248,22,152,16,2,58,11,11,248,22,152,16,2,59,86,95,23,195, -1,23,194,1,248,22,139,16,249,22,137,16,23,199,1,23,196,1,27,250,80, -144,47,43,42,248,22,152,16,2,58,23,197,1,10,28,23,193,2,248,22,139, -16,23,194,1,11,28,23,193,2,249,22,82,248,22,139,16,249,22,137,16,23, -198,1,247,22,153,16,27,248,22,164,20,23,198,1,28,248,22,90,23,194,2, -9,27,248,80,144,47,56,42,248,22,83,23,196,2,28,23,193,2,249,22,82, -248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,49,8,53, -42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144,47,8,53,42,248, -22,164,20,23,196,1,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248, -22,90,23,194,2,9,27,248,80,144,45,56,42,248,22,83,23,196,2,28,23, -193,2,249,22,82,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,248, -80,144,47,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144, -45,8,53,42,248,22,164,20,23,196,1,27,247,22,160,16,27,248,80,144,42, -58,42,247,80,144,42,57,42,249,80,144,43,44,41,28,23,196,2,27,249,22, -177,8,247,22,176,8,2,77,28,192,249,22,167,8,194,7,63,2,68,2,68, -250,80,144,46,8,23,42,23,198,2,2,78,27,28,23,200,1,250,22,129,16, -248,22,152,16,2,63,250,22,160,2,23,205,1,2,61,247,22,173,8,2,79, -86,94,23,199,1,11,27,248,80,144,49,8,50,42,250,22,96,9,248,22,92, -248,22,152,16,2,57,9,28,193,249,22,82,195,194,192,27,247,22,160,16,27, +45,112,97,116,104,115,75,101,109,98,101,100,100,101,100,45,108,111,97,100,78, +110,111,114,109,97,108,45,112,97,116,104,45,99,97,115,101,6,41,41,40,111, +114,47,99,32,112,97,116,104,45,102,111,114,45,115,111,109,101,45,115,121,115, +116,101,109,63,32,112,97,116,104,45,115,116,114,105,110,103,63,41,69,119,105, +110,100,111,119,115,6,2,2,92,49,6,41,41,40,111,114,47,99,32,112,97, +116,104,45,115,116,114,105,110,103,63,32,112,97,116,104,45,102,111,114,45,115, +111,109,101,45,115,121,115,116,101,109,63,41,6,4,4,112,97,116,104,5,8, +92,92,63,92,82,69,76,92,6,12,12,112,97,116,104,45,115,116,114,105,110, +103,63,70,114,101,108,97,116,105,118,101,66,108,111,111,112,5,0,6,30,30, +40,112,114,111,99,101,100,117,114,101,45,97,114,105,116,121,45,105,110,99,108, +117,100,101,115,47,99,32,48,41,6,21,21,105,110,118,97,108,105,100,32,114, +101,108,97,116,105,118,101,32,112,97,116,104,6,18,18,40,97,110,121,47,99, +32,46,32,45,62,32,46,32,97,110,121,41,74,99,111,108,108,101,99,116,115, +45,100,105,114,71,101,120,101,99,45,102,105,108,101,70,111,114,105,103,45,100, +105,114,72,99,111,110,102,105,103,45,100,105,114,79,105,110,115,116,97,108,108, +97,116,105,111,110,45,110,97,109,101,6,10,10,108,105,110,107,115,46,114,107, +116,100,71,97,100,100,111,110,45,100,105,114,71,102,115,45,99,104,97,110,103, +101,67,101,114,114,111,114,66,114,111,111,116,73,115,116,97,116,105,99,45,114, +111,111,116,6,0,0,6,1,1,47,5,3,46,122,111,6,40,40,114,101,109, +111,118,105,110,103,32,115,117,102,102,105,120,32,109,97,107,101,115,32,112,97, +116,104,32,101,108,101,109,101,110,116,32,101,109,112,116,121,6,10,10,103,105, +118,101,110,32,112,97,116,104,5,1,95,6,21,21,40,111,114,47,99,32,115, +116,114,105,110,103,63,32,98,121,116,101,115,63,41,6,36,36,99,97,110,110, +111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111,32,97,32, +114,111,111,116,32,112,97,116,104,58,32,68,102,105,110,105,115,104,5,11,80, +76,84,67,79,76,76,69,67,84,83,1,20,99,111,108,108,101,99,116,115,45, +115,101,97,114,99,104,45,100,105,114,115,6,8,8,99,111,108,108,101,99,116, +115,27,248,22,173,15,194,28,192,192,28,248,22,153,7,194,27,248,22,132,16, +195,28,192,192,248,22,133,16,195,11,0,21,35,114,120,34,94,91,92,92,93, +91,92,92,93,91,63,93,91,92,92,93,34,0,6,35,114,120,34,47,34,0, +22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91,47,92,92,93,42, +36,34,0,19,35,114,120,34,91,32,46,93,43,40,91,47,92,92,93,42,41, +36,34,86,94,28,28,248,22,174,15,23,195,2,10,28,248,22,173,15,23,195, +2,10,28,248,22,153,7,23,195,2,28,248,22,132,16,23,195,2,10,248,22, +133,16,23,195,2,11,12,250,22,180,11,2,41,2,42,23,197,2,28,28,248, +22,174,15,23,195,2,249,22,169,9,248,22,175,15,23,197,2,2,43,249,22, +169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,196,2,23,195,2,248, +22,165,8,248,22,178,15,23,197,2,28,249,22,170,16,2,79,23,195,2,28, +248,22,153,7,195,248,22,181,15,195,194,27,248,22,128,8,23,195,1,249,22, +182,15,248,22,168,8,250,22,178,16,2,80,28,249,22,170,16,2,81,23,201, +2,23,199,1,250,22,178,16,2,82,23,202,1,2,44,80,144,47,40,41,2, +43,28,248,22,153,7,194,248,22,181,15,194,193,0,28,35,114,120,34,94,92, +92,92,92,92,92,92,92,91,63,93,92,92,92,92,85,78,67,92,92,92,92, +34,86,95,28,28,28,248,22,173,15,23,195,2,10,28,248,22,153,7,23,195, +2,28,248,22,132,16,23,195,2,10,248,22,133,16,23,195,2,11,10,248,22, +174,15,23,195,2,12,252,22,180,11,2,6,2,45,39,23,199,2,23,200,2, +28,28,28,248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248, +22,132,16,23,196,2,10,248,22,133,16,23,196,2,11,10,248,22,174,15,23, +196,2,12,252,22,180,11,2,6,2,45,40,23,199,2,23,200,2,27,28,248, +22,174,15,23,196,2,248,22,175,15,23,196,2,247,22,176,15,86,95,28,28, +248,22,134,16,23,196,2,10,249,22,169,9,247,22,176,15,23,195,2,12,253, +22,182,11,2,6,6,54,54,112,97,116,104,32,105,115,32,110,111,116,32,99, +111,109,112,108,101,116,101,32,97,110,100,32,110,111,116,32,116,104,101,32,112, +108,97,116,102,111,114,109,39,115,32,99,111,110,118,101,110,116,105,111,110,2, +46,23,201,2,6,24,24,112,108,97,116,102,111,114,109,32,99,111,110,118,101, +110,116,105,111,110,32,116,121,112,101,247,22,176,15,28,249,22,169,9,28,248, +22,174,15,23,199,2,248,22,175,15,23,199,2,247,22,176,15,23,195,2,12, +253,22,182,11,2,6,6,37,37,103,105,118,101,110,32,112,97,116,104,115,32, +117,115,101,32,100,105,102,102,101,114,101,110,116,32,99,111,110,118,101,110,116, +105,111,110,115,2,46,23,201,2,6,9,9,114,111,111,116,32,112,97,116,104, +23,202,2,27,27,248,22,138,16,28,248,22,134,16,23,199,2,23,198,1,248, +22,135,16,23,199,1,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22, +173,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,132,16,23,194, +2,10,248,22,133,16,23,194,2,11,12,250,22,180,11,2,41,2,42,23,196, +2,28,28,248,22,174,15,23,194,2,249,22,169,9,248,22,175,15,23,196,2, +2,43,249,22,169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,195,2, +23,194,2,248,22,165,8,248,22,178,15,23,196,2,28,249,22,170,16,2,79, +23,195,2,28,248,22,153,7,194,248,22,181,15,194,193,27,248,22,128,8,23, +195,1,249,22,182,15,248,22,168,8,250,22,178,16,2,80,28,249,22,170,16, +2,81,23,201,2,23,199,1,250,22,178,16,2,82,23,202,1,2,44,80,144, +50,40,41,2,43,28,248,22,153,7,193,248,22,181,15,193,192,27,248,22,178, +15,23,195,2,28,249,22,169,9,23,197,2,66,117,110,105,120,28,249,22,150, +8,194,5,1,47,28,248,22,174,15,198,197,248,22,181,15,198,249,22,191,15, +199,249,22,182,15,249,22,153,8,248,22,178,15,200,40,198,28,249,22,169,9, +23,197,2,2,43,249,22,191,15,23,200,1,249,22,182,15,28,249,22,170,16, +0,27,35,114,120,34,94,92,92,92,92,92,92,92,92,91,63,93,92,92,92, +92,91,97,45,122,93,58,34,23,199,2,251,22,154,8,2,47,250,22,153,8, +203,43,44,5,1,92,249,22,153,8,202,45,28,249,22,170,16,2,84,23,199, +2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,170,16,2,84,23, +199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,170,16,0,14, +35,114,120,34,94,92,92,92,92,92,92,92,92,34,23,199,2,249,22,154,8, +5,4,85,78,67,92,249,22,153,8,200,41,28,249,22,170,16,0,12,35,114, +120,34,94,91,97,45,122,93,58,34,198,249,22,154,8,250,22,153,8,201,39, +40,249,22,153,8,200,41,12,198,12,32,86,88,148,8,36,42,56,11,72,102, +111,117,110,100,45,101,120,101,99,222,33,89,32,87,88,148,8,36,43,61,11, +66,110,101,120,116,222,33,88,27,248,22,136,16,23,196,2,28,249,22,171,9, +23,195,2,23,197,1,11,28,248,22,132,16,23,194,2,27,249,22,191,15,23, +197,1,23,196,1,28,23,197,2,90,144,42,11,89,146,42,39,11,248,22,130, +16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,2,27,248,22,136, +16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28,248,22,132,16, +23,194,2,250,2,86,23,205,2,23,206,2,249,22,191,15,23,200,2,23,198, +1,250,2,86,23,205,2,23,206,2,23,196,1,11,28,23,193,2,192,86,94, +23,193,1,27,28,248,22,173,15,23,196,2,27,249,22,191,15,23,198,2,23, +205,2,28,28,248,22,186,15,193,10,248,22,185,15,193,192,11,11,28,23,193, +2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,136,16,23,200,2,28, +249,22,171,9,194,23,201,1,11,28,248,22,132,16,193,250,2,86,205,206,249, +22,191,15,200,197,250,2,86,205,206,195,192,86,94,23,194,1,28,23,196,2, +90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,2,86,95,23,195,1, +23,194,1,27,28,23,201,2,27,248,22,136,16,23,199,2,28,249,22,171,9, +23,195,2,23,200,2,11,28,248,22,132,16,23,194,2,250,2,86,23,204,2, +23,205,2,249,22,191,15,23,200,2,23,198,1,250,2,86,23,204,2,23,205, +2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,173,15, +23,196,2,27,249,22,191,15,23,198,2,23,204,2,28,28,248,22,186,15,193, +10,248,22,185,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28,23, +202,2,11,27,248,22,136,16,23,200,2,28,249,22,171,9,194,23,201,1,11, +28,248,22,132,16,193,250,2,86,204,205,249,22,191,15,200,197,250,2,86,204, +205,195,192,28,23,193,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23, +199,2,86,95,23,195,1,23,194,1,27,28,23,198,2,251,2,87,23,198,2, +23,203,2,23,201,2,23,202,2,11,28,23,193,2,192,86,94,23,193,1,27, +28,248,22,173,15,195,27,249,22,191,15,197,200,28,28,248,22,186,15,193,10, +248,22,185,15,193,192,11,11,28,192,192,28,198,11,251,2,87,198,203,201,202, +194,32,90,88,148,8,36,43,60,11,2,50,222,33,91,28,248,22,88,23,197, +2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,201,2,23,196,2,28, +248,22,185,15,23,194,2,250,2,86,197,198,195,86,94,23,193,1,27,248,22, +162,20,23,199,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22,135, +16,248,22,81,23,198,2,23,198,2,28,248,22,185,15,23,194,2,250,2,86, +199,200,195,86,94,23,193,1,27,248,22,162,20,23,196,1,28,248,22,88,23, +194,2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,198,2,23,200,2, +28,248,22,185,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248, +22,162,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22, +135,16,248,22,81,197,201,28,248,22,185,15,193,250,2,86,203,204,195,251,2, +90,203,204,205,248,22,162,20,198,86,95,28,28,248,22,173,15,23,195,2,10, +28,248,22,153,7,23,195,2,28,248,22,132,16,23,195,2,10,248,22,133,16, +23,195,2,11,12,250,22,180,11,2,7,2,48,23,197,2,28,28,23,195,2, +28,28,248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22, +132,16,23,196,2,10,248,22,133,16,23,196,2,11,248,22,132,16,23,196,2, +11,10,12,250,22,180,11,2,7,6,45,45,40,111,114,47,99,32,35,102,32, +40,97,110,100,47,99,32,112,97,116,104,45,115,116,114,105,110,103,63,32,114, +101,108,97,116,105,118,101,45,112,97,116,104,63,41,41,23,198,2,28,28,248, +22,132,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,198, +2,249,22,169,9,194,2,49,11,27,249,22,175,8,247,22,174,8,5,4,80, +65,84,72,27,28,23,194,2,249,80,143,43,44,249,22,165,8,23,198,1,7, +63,9,86,94,23,194,1,9,27,28,249,22,169,9,247,22,180,8,2,43,249, +22,80,248,22,182,15,5,1,46,23,196,1,23,194,1,28,248,22,88,23,194, +2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,198,2,23,200,2,28, +248,22,185,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248,22, +162,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22,135, +16,248,22,81,23,198,2,23,202,2,28,248,22,185,15,23,194,2,250,2,86, +203,204,195,86,94,23,193,1,27,248,22,162,20,23,196,1,28,248,22,88,23, +194,2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,198,2,23,204,2, +28,248,22,185,15,23,194,2,250,2,86,205,206,195,86,94,23,193,1,27,248, +22,162,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22, +135,16,248,22,81,197,205,28,248,22,185,15,193,250,2,86,23,15,23,16,195, +251,2,90,23,15,23,16,23,17,248,22,162,20,198,27,248,22,135,16,23,196, +1,28,248,22,185,15,193,250,2,86,198,199,195,11,250,80,144,42,43,42,196, +197,11,250,80,144,42,43,42,196,11,11,32,95,88,148,8,36,42,58,11,2, +50,222,33,97,0,8,35,114,120,35,34,92,34,34,27,249,22,166,16,23,197, +2,23,198,2,28,23,193,2,86,94,23,196,1,27,248,22,102,23,195,2,27, +27,248,22,111,23,197,1,27,249,22,166,16,23,201,2,23,196,2,28,23,193, +2,86,94,23,194,1,27,248,22,102,23,195,2,27,250,2,95,202,23,204,1, +248,22,111,23,199,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22,178, +16,2,96,23,198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,202, +195,249,22,80,248,22,182,15,195,195,86,95,23,199,1,23,193,1,27,28,249, +22,169,9,247,22,180,8,2,43,250,22,178,16,2,96,23,198,1,2,51,194, +28,249,22,150,8,194,2,51,249,22,94,200,9,249,22,80,248,22,182,15,195, +9,27,28,249,22,169,9,247,22,180,8,2,43,250,22,178,16,2,96,23,198, +1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,198,195,249,22,80,248, +22,182,15,195,195,86,94,23,193,1,27,28,249,22,169,9,247,22,180,8,2, +43,250,22,178,16,2,96,23,200,1,2,51,196,28,249,22,150,8,194,2,51, +249,22,94,196,9,249,22,80,248,22,182,15,195,9,86,95,28,28,248,22,142, +8,194,10,248,22,153,7,194,12,250,22,180,11,2,8,6,21,21,40,111,114, +47,99,32,98,121,116,101,115,63,32,115,116,114,105,110,103,63,41,196,28,28, +248,22,89,195,249,22,4,22,173,15,196,11,12,250,22,180,11,2,8,6,14, +14,40,108,105,115,116,111,102,32,112,97,116,104,63,41,197,250,2,95,197,195, +28,248,22,153,7,197,248,22,167,8,197,196,28,28,248,22,0,23,195,2,249, +22,48,23,196,2,39,11,20,13,144,80,144,39,46,40,26,29,80,144,8,29, +47,40,249,22,31,11,80,144,8,31,46,40,22,143,15,10,22,144,15,10,22, +145,15,10,22,148,15,10,22,147,15,11,22,149,15,10,22,146,15,10,22,150, +15,10,22,151,15,10,22,152,15,10,22,153,15,10,22,154,15,11,22,155,15, +10,22,141,15,11,247,23,194,1,250,22,180,11,2,9,2,52,23,197,1,86, +94,28,28,248,22,173,15,23,195,2,10,28,248,22,153,7,23,195,2,28,248, +22,132,16,23,195,2,10,248,22,133,16,23,195,2,11,12,250,22,180,11,23, +196,2,2,48,23,197,2,28,248,22,132,16,23,195,2,12,251,22,182,11,23, +197,1,2,53,2,46,23,198,1,86,94,28,28,248,22,173,15,23,195,2,10, +28,248,22,153,7,23,195,2,28,248,22,132,16,23,195,2,10,248,22,133,16, +23,195,2,11,12,250,22,180,11,23,196,2,2,48,23,197,2,28,248,22,132, +16,23,195,2,12,251,22,182,11,23,197,1,2,53,2,46,23,198,1,86,94, +86,94,28,28,248,22,173,15,23,195,2,10,28,248,22,153,7,23,195,2,28, +248,22,132,16,23,195,2,10,248,22,133,16,23,195,2,11,12,250,22,180,11, +23,196,2,2,48,23,197,2,28,248,22,132,16,23,195,2,86,94,23,194,1, +12,251,22,182,11,23,197,2,2,53,2,46,23,198,1,249,22,3,20,20,94, +88,148,8,36,40,50,11,9,223,2,33,101,23,195,1,23,197,1,28,28,248, +22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22,180,11,23,196,1, +2,54,23,197,1,86,94,28,28,248,22,173,15,23,194,2,10,28,248,22,153, +7,23,194,2,28,248,22,132,16,23,194,2,10,248,22,133,16,23,194,2,11, +12,250,22,180,11,2,15,2,48,23,196,2,28,248,22,132,16,23,194,2,12, +251,22,182,11,2,15,2,53,2,46,23,197,1,86,95,86,94,86,94,28,28, +248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,132,16, +23,196,2,10,248,22,133,16,23,196,2,11,12,250,22,180,11,2,15,2,48, +23,198,2,28,248,22,132,16,23,196,2,12,251,22,182,11,2,15,2,53,2, +46,23,199,2,249,22,3,32,0,88,148,8,36,40,49,11,9,222,33,104,23, +198,2,28,28,248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22, +180,11,2,15,2,54,23,197,2,252,80,143,44,52,23,199,1,23,200,1,23, +201,1,11,11,86,94,28,28,248,22,173,15,23,194,2,10,28,248,22,153,7, +23,194,2,28,248,22,132,16,23,194,2,10,248,22,133,16,23,194,2,11,12, +250,22,180,11,2,17,2,48,23,196,2,28,248,22,132,16,23,194,2,12,251, +22,182,11,2,17,2,53,2,46,23,197,1,86,96,86,94,28,28,248,22,173, +15,23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,132,16,23,197,2, +10,248,22,133,16,23,197,2,11,12,250,22,180,11,2,17,2,48,23,199,2, +28,248,22,132,16,23,197,2,12,251,22,182,11,2,17,2,53,2,46,23,200, +2,86,94,86,94,28,28,248,22,173,15,23,198,2,10,28,248,22,153,7,23, +198,2,28,248,22,132,16,23,198,2,10,248,22,133,16,23,198,2,11,12,250, +22,180,11,2,17,2,48,23,200,2,28,248,22,132,16,23,198,2,12,251,22, +182,11,2,17,2,53,2,46,23,201,2,249,22,3,32,0,88,148,8,36,40, +49,11,9,222,33,106,23,200,2,28,28,248,22,0,23,195,2,249,22,48,23, +196,2,40,11,12,250,22,180,11,2,17,2,54,23,197,2,252,80,143,44,52, +23,199,1,23,202,1,23,203,1,23,201,1,23,200,1,27,248,22,150,16,2, +55,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248,22,133,16, +23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250, +80,144,49,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95, +23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23,196,1,27, +250,80,144,44,43,42,248,22,150,16,2,56,23,197,1,10,28,23,193,2,248, +22,137,16,23,194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42,27, +248,22,150,16,2,58,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1, +28,248,22,133,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16, +249,22,135,16,250,80,144,49,43,42,248,22,150,16,2,56,11,11,248,22,150, +16,2,57,86,95,23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199, +1,23,196,1,27,250,80,144,44,43,42,248,22,150,16,2,56,23,197,1,10, +28,23,193,2,248,22,137,16,23,194,1,11,249,80,144,41,55,40,40,80,144, +41,8,41,42,27,20,13,144,80,144,40,46,40,26,29,80,144,8,30,47,40, +249,22,31,11,80,144,8,32,46,40,22,143,15,10,22,144,15,10,22,145,15, +10,22,148,15,10,22,147,15,11,22,149,15,10,22,146,15,10,22,150,15,10, +22,151,15,10,22,152,15,10,22,153,15,10,22,154,15,11,22,155,15,10,22, +141,15,11,247,22,148,6,28,248,22,149,2,193,192,11,27,28,23,195,2,249, +22,191,15,23,197,1,6,11,11,99,111,110,102,105,103,46,114,107,116,100,86, +94,23,195,1,11,27,28,23,194,2,28,248,22,185,15,23,195,2,249,22,140, +6,23,196,1,80,144,43,8,42,42,11,11,28,192,192,21,17,1,0,250,22, +158,2,23,196,1,2,59,247,22,171,8,250,22,158,2,195,2,59,247,22,171, +8,28,248,22,153,7,23,195,2,27,248,22,181,15,23,196,1,28,248,22,134, +16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144,43,54,42,28,23, +193,2,192,86,94,23,193,1,247,22,151,16,28,248,22,142,8,23,195,2,27, +248,22,182,15,23,196,1,28,248,22,134,16,23,194,2,192,249,22,135,16,23, +195,1,27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22, +151,16,28,248,22,173,15,23,195,2,28,248,22,134,16,23,195,2,193,249,22, +135,16,23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23,193, +1,247,22,151,16,193,27,248,22,150,16,2,55,28,248,22,134,16,23,194,2, +248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42,11,89,146, +42,39,11,248,22,130,16,249,22,135,16,250,80,144,49,43,42,248,22,150,16, +2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1,248,22,137, +16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,150, +16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1,11,28,248, +22,134,16,23,195,2,193,249,22,135,16,23,196,1,27,249,80,144,44,55,40, +39,80,144,44,8,43,42,28,23,193,2,192,86,94,23,193,1,247,22,151,16, +28,248,22,134,16,23,195,2,248,22,137,16,23,195,1,28,248,22,133,16,23, +195,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80, +144,48,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23, +195,1,23,194,1,248,22,137,16,249,22,135,16,23,200,1,23,196,1,27,250, +80,144,43,43,42,248,22,150,16,2,56,23,198,1,10,28,23,193,2,248,22, +137,16,23,194,1,11,28,248,22,88,23,196,2,9,28,248,22,81,23,196,2, +249,22,80,27,248,22,161,20,23,199,2,28,248,22,153,7,23,194,2,27,248, +22,181,15,23,195,1,28,248,22,134,16,23,194,2,192,249,22,135,16,23,195, +1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,151, +16,28,248,22,142,8,23,194,2,27,248,22,182,15,23,195,1,28,248,22,134, +16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144,46,54,42,28,23, +193,2,192,86,94,23,193,1,247,22,151,16,28,248,22,173,15,23,194,2,28, +248,22,134,16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144,45,54, +42,28,23,193,2,192,86,94,23,193,1,247,22,151,16,192,27,248,22,162,20, +23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80, +248,80,144,45,60,42,248,22,161,20,23,197,2,27,248,22,162,20,23,197,1, +28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144, +48,60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, +22,162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, +1,248,22,162,20,23,198,1,249,22,94,23,199,2,27,248,22,162,20,23,197, +1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80, +144,48,60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1, +248,22,162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, +204,1,248,22,162,20,23,198,1,249,22,94,23,196,2,27,248,22,162,20,23, +199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248, +80,144,45,60,42,248,22,161,20,23,197,2,27,248,22,162,20,23,197,1,28, +248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144,48, +60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22, +162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1, +248,22,162,20,23,198,1,249,22,94,23,199,2,27,248,22,162,20,23,197,1, +28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144, +48,60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, +22,162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, +1,248,22,162,20,23,198,1,27,250,22,158,2,23,198,1,23,199,1,11,28, +192,249,80,144,42,8,44,42,198,194,196,27,248,22,150,16,2,58,28,248,22, +134,16,23,194,2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90, +144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,49,43, +42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23, +194,1,248,22,137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,44, +43,42,248,22,150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23, +194,1,11,27,248,80,144,41,58,42,249,80,144,43,55,40,40,80,144,43,8, +45,42,27,27,250,22,158,2,23,198,2,72,108,105,110,107,115,45,102,105,108, +101,11,27,28,23,194,2,23,194,1,86,94,23,194,1,249,22,191,15,27,250, +22,158,2,23,202,2,71,115,104,97,114,101,45,100,105,114,11,28,192,192,249, +22,191,15,64,117,112,6,5,5,115,104,97,114,101,2,60,28,248,22,153,7, +23,194,2,27,248,22,181,15,23,195,1,28,248,22,134,16,23,194,2,192,249, +22,135,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23, +193,1,247,22,151,16,28,248,22,142,8,23,194,2,27,248,22,182,15,23,195, +1,28,248,22,134,16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144, +47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,151,16,28,248,22,173, +15,23,194,2,28,248,22,134,16,23,194,2,192,249,22,135,16,23,195,1,27, +247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,151,16,192, +250,22,94,248,22,90,11,28,247,22,158,16,28,247,22,159,16,248,22,90,250, +22,191,15,248,22,150,16,2,61,250,22,158,2,23,204,2,2,59,247,22,171, +8,2,60,9,9,28,247,22,159,16,250,80,144,47,8,23,42,23,200,1,1, +18,108,105,110,107,115,45,115,101,97,114,99,104,45,102,105,108,101,115,248,22, +90,23,200,1,9,248,22,172,13,23,194,1,249,22,14,80,144,41,8,26,41, +28,248,22,128,13,23,197,2,86,94,23,196,1,32,0,88,148,8,36,39,44, +11,9,222,11,20,20,94,88,148,8,36,39,46,11,9,223,3,33,124,23,196, +1,32,126,88,148,39,40,59,11,2,50,222,33,127,90,144,42,11,89,146,42, +39,11,248,22,130,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,173, +15,23,194,2,28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0, +88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22, +130,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2, +28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, +39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197, +1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186, +15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9, +222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,1,86,95,23, +195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186,15,23,194,2, +249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248,2, +126,23,194,1,11,11,11,11,32,128,2,88,148,8,36,40,58,11,2,50,222, +33,129,2,27,249,22,163,6,8,128,128,23,196,2,28,248,22,148,7,23,194, +2,9,249,22,80,23,195,1,27,249,22,163,6,8,128,128,23,199,2,28,248, +22,148,7,23,194,2,9,249,22,80,23,195,1,27,249,22,163,6,8,128,128, +23,202,2,28,248,22,148,7,23,194,2,9,249,22,80,23,195,1,27,249,22, +163,6,8,128,128,23,205,2,28,248,22,148,7,23,194,2,9,249,22,80,23, +195,1,248,2,128,2,23,206,1,27,249,22,163,6,8,128,128,23,196,2,28, +248,22,142,8,23,194,2,28,249,22,132,4,248,22,147,8,23,196,2,8,128, +128,249,22,1,22,154,8,249,22,80,23,197,1,27,249,22,163,6,8,128,128, +23,201,2,28,248,22,148,7,23,194,2,9,249,22,80,23,195,1,27,249,22, +163,6,8,128,128,23,204,2,28,248,22,148,7,23,194,2,9,249,22,80,23, +195,1,27,249,22,163,6,8,128,128,23,207,2,28,248,22,148,7,23,194,2, +9,249,22,80,23,195,1,27,249,22,163,6,8,128,128,23,210,2,28,248,22, +148,7,23,194,2,9,249,22,80,23,195,1,248,2,128,2,23,211,1,192,192, +248,22,133,6,23,194,1,20,13,144,80,144,40,8,28,40,80,144,40,8,46, +42,27,28,249,22,189,8,248,22,180,8,2,62,41,90,144,42,11,89,146,42, +39,11,248,22,130,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22,173, +15,23,194,2,28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0, +88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22, +130,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2, +28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, +39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197, +1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186, +15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9, +222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,1,86,95,23, +195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186,15,23,194,2, +249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248,2, +126,23,194,1,11,11,11,11,11,28,248,22,185,15,23,195,2,27,28,249,22, +189,8,248,22,180,8,2,62,41,249,22,145,6,23,197,2,32,0,88,148,8, +36,39,44,11,9,222,11,11,86,94,28,23,194,2,248,22,147,6,23,195,1, +86,94,23,194,1,12,249,22,80,27,248,22,188,5,23,199,1,250,22,44,22, +35,88,148,39,39,8,24,11,9,223,3,33,130,2,20,20,94,88,148,8,36, +39,46,11,9,223,3,33,131,2,23,196,1,194,249,22,80,11,194,28,28,23, +195,2,28,248,22,82,23,196,2,248,22,167,9,249,22,174,14,39,248,22,162, +20,23,199,2,11,11,194,86,94,23,195,1,249,22,12,20,20,94,88,148,8, +32,39,61,16,4,39,8,128,80,8,240,0,64,0,0,39,9,224,2,3,33, +132,2,23,196,1,80,144,41,8,26,41,27,248,22,167,9,194,28,192,192,248, +22,167,9,248,22,81,195,86,95,28,248,22,149,12,23,198,2,27,247,22,141, +12,28,249,22,131,12,23,195,2,2,63,251,22,137,12,23,197,1,2,63,250, +22,137,8,6,42,42,101,114,114,111,114,32,114,101,97,100,105,110,103,32,99, +111,108,108,101,99,116,105,111,110,32,108,105,110,107,115,32,102,105,108,101,32, +126,115,58,32,126,97,23,203,2,248,22,145,12,23,206,2,247,22,27,12,12, +28,23,193,2,250,22,156,2,80,144,45,8,25,41,23,198,1,249,22,80,23, +198,1,21,17,0,0,86,95,23,195,1,23,193,1,12,28,248,22,149,12,23, +198,2,86,94,23,197,1,248,23,195,1,247,22,138,2,196,88,148,39,40,58, +8,240,0,0,0,2,9,226,0,2,1,3,33,135,2,20,20,94,248,22,148, +6,23,194,2,28,248,22,148,7,248,22,148,6,23,195,1,12,248,22,176,11, +6,30,30,101,120,112,101,99,116,101,100,32,97,32,115,105,110,103,108,101,32, +83,45,101,120,112,114,101,115,115,105,111,110,248,22,133,6,23,194,1,28,248, +22,89,193,28,28,249,22,128,4,41,248,22,93,195,10,249,22,128,4,42,248, +22,93,195,28,28,248,22,153,7,248,22,81,194,10,28,249,22,169,9,2,64, +248,22,161,20,195,10,249,22,169,9,2,65,248,22,161,20,195,28,27,248,22, +102,194,28,248,22,173,15,193,10,28,248,22,153,7,193,28,248,22,132,16,193, +10,248,22,133,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22,179, +16,248,22,111,195,11,11,11,11,28,248,22,186,15,249,22,191,15,23,196,2, +23,198,2,27,248,22,68,248,22,177,15,23,198,1,250,22,156,2,23,198,2, +23,196,2,249,22,80,23,199,1,250,22,158,2,23,203,1,23,201,1,9,12, +250,22,156,2,23,197,1,23,198,1,249,22,80,23,198,1,23,201,1,28,28, +248,22,88,248,22,104,23,197,2,10,249,22,170,16,248,22,111,23,198,2,247, +22,171,8,27,248,22,137,16,249,22,135,16,248,22,102,23,200,2,23,198,1, +28,249,22,169,9,248,22,161,20,23,199,2,2,65,86,94,23,196,1,249,22, +3,20,20,94,88,148,8,36,40,56,11,9,224,3,2,33,140,2,23,196,1, +248,22,140,16,23,196,1,28,249,22,169,9,248,22,161,20,23,199,2,2,64, +86,94,23,196,1,86,94,28,250,22,158,2,23,197,2,11,11,12,250,22,156, +2,23,197,2,11,9,249,22,164,2,23,196,2,20,20,95,88,148,8,36,41, +53,11,9,224,3,2,33,141,2,23,195,1,23,196,1,27,248,22,68,248,22, +161,20,23,199,1,250,22,156,2,23,198,2,23,196,2,249,22,80,248,22,129, +2,23,200,1,250,22,158,2,23,203,1,23,201,1,9,12,250,22,156,2,23, +196,1,23,197,1,248,22,95,23,199,1,27,28,28,23,194,2,248,22,167,9, +248,22,81,23,196,2,10,9,27,249,22,188,5,23,198,2,68,98,105,110,97, +114,121,250,22,44,22,35,88,148,8,36,39,47,11,9,223,3,33,137,2,20, +20,94,88,148,8,36,39,46,11,9,223,3,33,138,2,23,196,1,86,94,28, +28,248,22,89,23,194,2,249,22,4,32,0,88,148,8,36,40,48,11,9,222, +33,139,2,23,195,2,11,12,248,22,176,11,6,18,18,105,108,108,45,102,111, +114,109,101,100,32,99,111,110,116,101,110,116,27,247,22,138,2,27,90,144,42, +11,89,146,42,39,11,248,22,130,16,23,201,2,192,86,96,249,22,3,20,20, +94,88,148,8,36,40,57,11,9,224,2,3,33,142,2,23,195,1,23,197,1, +249,22,164,2,195,88,148,8,36,41,51,11,9,223,3,33,143,2,250,22,156, +2,80,144,47,8,25,41,23,200,1,249,22,80,23,201,1,198,193,20,13,144, +80,144,40,8,28,40,250,80,144,43,8,47,42,23,198,2,23,196,2,11,27, +250,22,158,2,80,144,44,8,25,41,23,197,2,21,143,11,17,0,0,27,248, +22,81,23,195,2,27,249,80,144,45,8,27,42,23,198,2,23,196,2,28,249, +22,171,9,23,195,2,23,196,1,248,22,162,20,195,86,94,23,195,1,20,13, +144,80,144,43,8,28,40,250,80,144,46,8,47,42,23,201,1,23,199,2,23, +196,2,27,20,20,95,88,148,8,36,39,55,8,240,0,0,0,2,9,225,5, +4,1,33,144,2,23,194,1,23,197,1,28,249,22,48,23,195,2,39,20,13, +144,80,144,44,46,40,26,29,80,144,8,34,47,40,249,22,31,11,80,144,8, +36,46,40,22,143,15,10,22,144,15,10,22,145,15,10,22,148,15,10,22,147, +15,11,22,149,15,10,22,146,15,10,22,150,15,10,22,151,15,10,22,152,15, +10,22,153,15,10,22,154,15,11,22,155,15,10,22,141,15,11,247,23,193,1, +250,22,180,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39,40, +8,43,16,4,8,128,6,8,128,104,8,240,0,128,0,0,39,9,224,1,2, +33,145,2,23,195,1,0,7,35,114,120,34,47,43,34,28,248,22,153,7,23, +195,2,27,249,22,168,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128, +4,248,22,101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7, +250,22,175,7,23,200,1,39,248,22,101,23,199,1,23,198,1,249,22,7,250, +22,175,7,23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23, +201,1,248,22,103,23,200,1,23,200,1,249,22,7,23,197,1,23,198,1,90, +144,42,11,89,146,42,39,11,248,22,130,16,23,198,1,86,94,23,195,1,28, +249,22,169,9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23, +200,1,27,249,22,80,23,197,1,23,201,1,28,248,22,153,7,23,195,2,27, +249,22,168,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128,4,248,22, +101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7,250,22,175, +7,23,200,1,39,248,22,101,23,199,1,23,196,1,249,22,7,250,22,175,7, +23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23,201,1,248, +22,103,23,200,1,23,198,1,249,22,7,23,197,1,23,196,1,90,144,42,11, +89,146,42,39,11,248,22,130,16,23,198,1,86,94,23,195,1,28,249,22,169, +9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23,198,1,249, +80,144,48,8,31,42,194,249,22,80,197,199,28,248,22,88,23,196,2,9,28, +248,22,81,23,196,2,28,248,22,149,2,248,22,161,20,23,197,2,250,22,94, +249,22,2,22,129,2,250,22,158,2,248,22,161,20,23,204,2,23,202,2,9, +250,22,158,2,248,22,161,20,23,202,2,11,9,27,248,22,162,20,23,200,1, +28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248, +22,161,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22, +161,20,23,202,2,23,206,2,9,250,22,158,2,248,22,161,20,23,200,2,11, +9,249,80,144,48,8,48,42,23,203,1,248,22,162,20,23,199,1,27,248,80, +144,45,8,30,42,248,22,161,20,23,196,2,250,22,94,250,22,158,2,23,199, +2,23,205,2,9,250,22,158,2,23,199,1,11,9,249,80,144,49,8,48,42, +23,204,1,248,22,162,20,23,200,1,249,22,94,247,22,154,16,249,80,144,47, +8,48,42,23,202,1,248,22,162,20,23,198,1,27,248,80,144,41,8,30,42, +248,22,161,20,23,198,2,250,22,94,250,22,158,2,23,199,2,23,201,2,9, +250,22,158,2,23,199,1,11,9,27,248,22,162,20,23,201,1,28,248,22,88, +23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,161,20,23, +195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,161,20,23,202, +2,23,207,2,9,250,22,158,2,248,22,161,20,23,200,2,11,9,249,80,144, +49,8,48,42,23,204,1,248,22,162,20,23,199,1,27,248,80,144,46,8,30, +42,248,22,161,20,23,196,2,250,22,94,250,22,158,2,23,199,2,23,206,2, +9,250,22,158,2,23,199,1,11,9,249,80,144,50,8,48,42,23,205,1,248, +22,162,20,23,200,1,249,22,94,247,22,154,16,249,80,144,48,8,48,42,23, +203,1,248,22,162,20,23,198,1,249,22,94,247,22,154,16,27,248,22,162,20, +23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22, +149,2,248,22,161,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158, +2,248,22,161,20,23,202,2,23,205,2,9,250,22,158,2,248,22,161,20,23, +200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,162,20,23,199,1, +27,248,80,144,44,8,30,42,248,22,161,20,23,196,2,250,22,94,250,22,158, +2,23,199,2,23,204,2,9,250,22,158,2,23,199,1,11,9,249,80,144,48, +8,48,42,23,203,1,248,22,162,20,23,200,1,249,22,94,247,22,154,16,249, +80,144,46,8,48,42,23,201,1,248,22,162,20,23,198,1,32,150,2,88,148, +8,36,40,50,11,2,50,222,33,151,2,28,248,22,88,248,22,82,23,195,2, +248,22,90,27,248,22,161,20,195,28,248,22,173,15,193,248,22,177,15,193,192, +250,22,91,27,248,22,161,20,23,198,2,28,248,22,173,15,193,248,22,177,15, +193,192,2,67,248,2,150,2,248,22,162,20,23,198,1,250,22,137,8,6,7, +7,10,32,126,97,32,126,97,6,1,1,32,23,196,1,249,22,137,8,6,6, +6,10,32,32,32,126,97,248,22,132,2,23,196,1,32,154,2,88,148,39,41, +51,11,68,102,105,108,116,101,114,222,33,155,2,28,248,22,88,23,195,2,9, +28,248,23,194,2,248,22,81,23,196,2,249,22,80,248,22,161,20,23,197,2, +249,2,154,2,23,197,1,248,22,162,20,23,199,1,249,2,154,2,23,195,1, +248,22,162,20,23,197,1,28,248,22,88,23,201,2,86,95,23,200,1,23,199, +1,28,23,201,2,28,197,249,22,191,15,202,199,200,27,28,248,22,88,23,198, +2,2,66,249,22,1,22,176,7,248,2,150,2,23,200,2,248,23,199,1,251, +22,137,8,6,70,70,99,111,108,108,101,99,116,105,111,110,32,110,111,116,32, +102,111,117,110,100,10,32,32,99,111,108,108,101,99,116,105,111,110,58,32,126, +115,10,32,32,105,110,32,99,111,108,108,101,99,116,105,111,110,32,100,105,114, +101,99,116,111,114,105,101,115,58,126,97,126,97,28,248,22,88,23,203,1,28, +248,22,173,15,23,202,2,248,22,177,15,23,202,1,23,201,1,250,22,176,7, +28,248,22,173,15,23,205,2,248,22,177,15,23,205,1,23,204,1,2,67,23, +201,2,249,22,1,22,176,7,249,22,2,32,0,88,148,8,36,40,48,11,9, +222,33,152,2,27,248,22,93,23,206,2,27,248,22,93,247,22,154,16,28,249, +22,129,4,249,22,184,3,23,198,2,23,197,2,44,23,206,2,249,22,94,247, +22,154,16,248,22,90,249,22,137,8,6,50,50,46,46,46,32,91,126,97,32, +97,100,100,105,116,105,111,110,97,108,32,108,105,110,107,101,100,32,97,110,100, +32,112,97,99,107,97,103,101,32,100,105,114,101,99,116,111,114,105,101,115,93, +249,22,184,3,23,201,1,23,200,1,28,249,22,5,22,131,2,23,202,2,250, +22,137,8,6,49,49,10,32,32,32,115,117,98,45,99,111,108,108,101,99,116, +105,111,110,58,32,126,115,10,32,32,105,110,32,112,97,114,101,110,116,32,100, +105,114,101,99,116,111,114,105,101,115,58,126,97,23,201,1,249,22,1,22,176, +7,249,22,2,32,0,88,148,8,36,40,48,11,9,222,33,153,2,249,2,154, +2,22,131,2,23,209,1,86,95,23,200,1,23,198,1,2,66,27,248,22,81, +23,202,2,27,28,248,22,173,15,23,195,2,249,22,191,15,23,196,1,23,199, +2,248,22,132,2,23,195,1,28,28,248,22,173,15,248,22,161,20,23,204,2, +248,22,186,15,23,194,2,10,27,250,22,1,22,191,15,23,197,1,23,202,2, +28,28,248,22,88,23,200,2,10,248,22,186,15,23,194,2,28,23,201,2,28, +28,250,80,144,45,8,32,42,195,203,204,10,27,28,248,22,173,15,202,248,22, +177,15,202,201,19,248,22,156,7,23,195,2,27,28,249,22,132,4,23,196,4, +43,28,249,22,159,7,6,4,4,46,114,107,116,249,22,175,7,23,199,2,249, +22,184,3,23,200,4,43,249,22,176,7,250,22,175,7,23,200,1,39,249,22, +184,3,23,201,4,43,6,3,3,46,115,115,86,94,23,195,1,11,11,28,23, +193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249,22, +191,15,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16,23, +17,248,22,162,20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8,49, +42,204,205,206,23,15,23,16,23,17,248,22,162,20,23,19,23,19,26,8,80, +144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,162,20,23,18,23,18, +90,144,41,11,89,146,41,39,11,249,80,144,43,8,31,42,23,199,1,23,200, +1,27,248,22,68,28,248,22,173,15,195,248,22,177,15,195,194,27,27,247,22, +155,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149, +2,248,22,161,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, +248,22,161,20,23,202,2,23,203,2,9,250,22,158,2,248,22,161,20,23,200, +2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,162,20,23,199,1,27, +248,80,144,46,8,30,42,248,22,161,20,23,196,2,250,22,94,250,22,158,2, +23,199,2,23,202,2,9,250,22,158,2,23,199,1,11,9,249,80,144,50,8, +48,42,23,201,1,248,22,162,20,23,200,1,249,22,94,247,22,154,16,249,80, +144,48,8,48,42,23,199,1,248,22,162,20,23,198,1,26,8,80,144,51,8, +49,42,200,202,203,205,23,16,23,17,200,11,32,158,2,88,148,8,36,42,59, +11,2,50,222,33,159,2,28,248,22,133,4,23,196,2,86,94,23,195,1,19, +248,22,147,8,23,195,2,19,248,22,147,8,23,196,2,249,22,183,15,27,251, +22,154,8,250,22,153,8,23,205,2,39,23,204,4,2,51,249,22,153,8,23, +204,1,23,202,4,2,68,28,248,22,133,4,248,22,147,8,23,195,2,86,94, +23,193,1,251,22,182,11,2,37,2,69,2,70,202,192,28,248,22,174,15,198, +248,22,175,15,198,247,22,176,15,2,2,27,248,22,182,3,23,197,1,28,249, +22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248,22,181,3,23, +195,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204, +1,2,71,249,22,153,8,23,204,1,23,202,1,2,68,28,248,22,133,4,248, +22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70, +202,192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15,250,2,158,2, +196,197,195,248,22,185,15,27,250,22,191,15,23,200,1,23,202,1,23,199,1, +28,249,22,169,9,23,197,2,66,115,97,109,101,192,28,248,22,132,16,23,196, +2,249,22,191,15,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249,22, +5,20,20,96,88,148,39,40,54,47,9,226,5,4,2,6,33,160,2,23,199, +1,23,195,1,23,197,1,23,196,1,27,248,22,185,15,249,22,191,15,23,198, +2,23,199,2,28,23,193,2,192,86,94,23,193,1,28,23,197,1,27,90,144, +41,11,89,146,41,39,11,250,80,144,46,8,34,42,23,202,2,2,68,2,37, +27,248,22,179,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248,22, +147,8,23,198,1,28,248,22,174,15,195,249,22,191,15,196,194,192,27,247,22, +156,16,249,22,5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3,33, +161,2,23,196,1,23,195,1,23,199,1,247,22,157,16,11,86,95,28,28,248, +22,174,15,23,194,2,10,28,248,22,173,15,23,194,2,10,28,248,22,153,7, +23,194,2,28,248,22,132,16,23,194,2,10,248,22,133,16,23,194,2,11,12, +252,22,180,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22,153, +7,23,195,2,10,248,22,142,8,23,195,2,86,94,23,194,1,12,252,22,180, +11,23,200,2,2,72,40,23,198,2,23,199,1,90,144,42,11,89,146,42,39, +11,248,22,130,16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86,95, +23,198,1,23,196,1,12,250,22,183,11,23,201,1,2,73,23,199,1,249,22, +7,23,195,1,23,196,1,32,164,2,88,148,8,36,46,61,11,2,74,222,33, +165,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,203,2,39,23,207, +1,23,205,1,249,23,203,1,23,202,1,23,208,1,28,248,22,153,7,23,204, +2,249,22,168,8,23,205,1,8,63,23,203,1,28,248,22,133,4,248,22,147, +8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,201,192, +28,248,22,174,15,197,248,22,175,15,197,247,22,176,15,32,166,2,88,148,8, +36,45,8,24,11,2,50,222,33,167,2,28,248,22,133,4,23,199,2,86,95, +23,198,1,23,194,1,19,248,22,147,8,23,195,2,19,248,22,147,8,23,196, +2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204,4, +2,51,249,23,206,1,23,204,1,23,202,4,28,248,22,153,7,23,207,2,249, +22,168,8,23,208,1,8,63,23,206,1,28,248,22,133,4,248,22,147,8,23, +195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,204,192,28,248, +22,174,15,200,248,22,175,15,200,247,22,176,15,2,2,27,248,22,182,3,23, +200,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248, +22,181,3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205, +2,39,23,204,1,23,203,1,249,23,206,1,23,204,1,23,202,1,28,248,22, +153,7,23,207,2,249,22,168,8,23,208,1,8,63,23,206,1,28,248,22,133, +4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69, +2,70,204,192,28,248,22,174,15,200,248,22,175,15,200,247,22,176,15,28,248, +22,133,4,23,194,2,86,95,23,195,1,23,193,1,19,248,22,147,8,23,196, +2,19,248,22,147,8,23,197,2,249,22,183,15,27,251,22,154,8,250,22,153, +8,23,206,2,39,23,204,4,2,51,249,23,207,1,23,205,1,23,202,4,28, +248,22,153,7,23,208,2,249,22,168,8,23,209,1,8,63,23,207,1,28,248, +22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37, +2,69,2,70,205,192,28,248,22,174,15,201,248,22,175,15,201,247,22,176,15, +2,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148,8, +23,199,2,23,197,2,27,248,22,181,3,23,195,2,249,22,183,15,27,251,22, +154,8,250,22,153,8,23,206,2,39,23,204,1,23,204,1,249,23,207,1,23, +205,1,23,202,1,28,248,22,153,7,23,208,2,249,22,168,8,23,209,1,8, +63,23,207,1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1, +251,22,182,11,2,37,2,69,2,70,205,192,28,248,22,174,15,201,248,22,175, +15,201,247,22,176,15,28,248,22,133,4,193,254,2,164,2,201,203,204,205,248, +22,147,8,202,2,51,248,22,147,8,202,27,248,22,182,3,194,28,249,22,169, +9,8,46,249,22,148,8,199,196,254,2,164,2,202,204,205,206,199,203,248,22, +181,3,200,253,2,166,2,201,202,203,204,205,198,90,144,41,11,89,146,41,39, +11,86,95,28,28,248,22,174,15,23,199,2,10,28,248,22,173,15,23,199,2, +10,28,248,22,153,7,23,199,2,28,248,22,132,16,23,199,2,10,248,22,133, +16,23,199,2,11,12,252,22,180,11,23,200,2,2,42,39,23,203,2,23,204, +2,28,28,248,22,153,7,23,200,2,10,248,22,142,8,23,200,2,12,252,22, +180,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146,42, +39,11,248,22,130,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250,22, +183,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,179,15,23, +196,1,27,19,248,22,147,8,23,196,2,28,248,22,133,4,23,194,4,86,94, +23,199,1,19,248,22,147,8,23,197,2,19,248,22,147,8,23,198,2,249,22, +183,15,27,251,22,154,8,250,22,153,8,23,207,2,39,23,204,4,2,51,249, +23,211,1,23,206,1,23,202,4,28,248,22,153,7,23,212,2,249,22,168,8, +23,213,1,8,63,23,211,1,28,248,22,133,4,248,22,147,8,23,195,2,86, +94,23,193,1,251,22,182,11,2,37,2,69,2,70,23,17,192,28,248,22,174, +15,205,248,22,175,15,205,247,22,176,15,2,2,27,248,22,182,3,23,195,4, +28,249,22,169,9,8,46,249,22,148,8,23,200,2,23,197,2,27,248,22,181, +3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,207,2,39, +23,204,1,23,208,1,249,23,211,1,23,206,1,23,202,1,28,248,22,153,7, +23,212,2,249,22,168,8,23,213,1,8,63,23,211,1,28,248,22,133,4,248, +22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70, +23,17,192,28,248,22,174,15,205,248,22,175,15,205,247,22,176,15,28,248,22, +133,4,23,194,2,86,95,23,200,1,23,193,1,254,2,164,2,23,203,2,23, +208,1,23,209,1,23,210,1,248,22,147,8,23,204,2,2,51,248,22,147,8, +23,204,1,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148, +8,23,201,2,23,197,2,254,2,164,2,23,204,1,23,209,1,23,210,1,23, +211,1,23,200,2,23,208,1,248,22,181,3,23,201,1,253,2,166,2,23,203, +1,23,207,1,23,208,1,23,209,1,23,210,1,23,199,1,2,28,248,22,174, +15,195,249,22,191,15,196,194,192,32,169,2,88,148,8,36,43,61,11,2,50, +222,33,170,2,28,248,22,133,4,23,197,2,86,94,23,196,1,19,248,22,147, +8,23,195,2,35,248,22,147,8,23,196,2,249,22,183,15,27,251,22,154,8, +250,22,153,8,23,205,1,39,23,204,4,2,51,2,51,28,248,22,153,7,23, +205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22, +147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,202, +192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15,2,27,248,22,182, +3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2, +35,248,22,181,3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153,8, +23,205,1,39,23,204,1,2,51,2,51,28,248,22,153,7,23,205,2,249,22, +168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22,147,8,23,195, +2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,202,192,28,248,22, +174,15,198,248,22,175,15,198,247,22,176,15,28,248,22,133,4,23,194,2,86, +94,23,193,1,19,248,22,147,8,23,196,2,35,248,22,147,8,23,197,2,249, +22,183,15,27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,4,2,51, +2,51,28,248,22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205, +1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182, +11,2,37,2,69,2,70,203,192,28,248,22,174,15,199,248,22,175,15,199,247, +22,176,15,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22, +148,8,23,199,2,23,197,2,35,248,22,181,3,23,195,2,249,22,183,15,27, +251,22,154,8,250,22,153,8,23,206,1,39,23,204,1,2,51,2,51,28,248, +22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205,1,28,248,22, +133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2, +69,2,70,203,192,28,248,22,174,15,199,248,22,175,15,199,247,22,176,15,251, +2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248, +22,174,15,23,196,2,10,28,248,22,173,15,23,196,2,10,28,248,22,153,7, +23,196,2,28,248,22,132,16,23,196,2,10,248,22,133,16,23,196,2,11,12, +252,22,180,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7, +23,197,2,10,248,22,142,8,23,197,2,12,252,22,180,11,2,37,2,72,40, +23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,199, +2,86,94,23,195,1,86,94,28,192,12,250,22,183,11,2,37,2,73,23,201, +2,249,22,7,194,195,27,248,22,179,15,23,196,1,27,251,2,169,2,23,198, +2,23,201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,174,15,195,249, +22,191,15,196,194,192,2,51,252,80,144,44,8,35,42,2,37,2,51,32,0, +88,148,8,36,41,46,11,9,222,33,172,2,198,199,32,174,2,88,148,8,36, +43,60,11,2,50,222,33,177,2,32,175,2,88,148,8,36,45,60,11,2,74, +222,33,176,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,203,2,39, +23,206,1,23,204,1,249,22,153,8,23,202,1,23,207,1,28,248,22,153,7, +23,203,2,249,22,168,8,23,204,1,8,63,23,202,1,28,248,22,133,4,248, +22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70, +200,192,28,248,22,174,15,196,248,22,175,15,196,247,22,176,15,28,248,22,133, +4,23,197,2,86,94,23,196,1,19,248,22,147,8,23,195,2,19,248,22,147, +8,23,196,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205,2,39, +23,204,4,2,51,249,22,153,8,23,204,1,23,202,4,28,248,22,153,7,23, +205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22, +147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,202, +192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15,2,2,27,248,22, +182,3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197, +2,27,248,22,181,3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153, +8,23,205,2,39,23,204,1,2,71,249,22,153,8,23,204,1,23,202,1,28, +248,22,153,7,23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248, +22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37, +2,69,2,70,202,192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15, +28,248,22,133,4,193,253,2,175,2,199,200,201,248,22,147,8,200,2,51,248, +22,147,8,200,27,248,22,182,3,194,28,249,22,169,9,8,46,249,22,148,8, +198,196,253,2,175,2,200,201,202,198,2,71,248,22,181,3,199,251,2,174,2, +198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,174,15, +23,196,2,10,28,248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2, +28,248,22,132,16,23,196,2,10,248,22,133,16,23,196,2,11,12,252,22,180, +11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7,23,197,2, +10,248,22,142,8,23,197,2,12,252,22,180,11,2,37,2,72,40,23,200,2, +23,201,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,199,2,86,94, +23,195,1,86,94,28,192,12,250,22,183,11,2,37,2,73,23,201,2,249,22, +7,194,195,27,248,22,179,15,23,196,1,27,251,2,174,2,23,198,2,23,201, +1,23,202,1,248,22,147,8,23,199,1,28,248,22,174,15,195,249,22,191,15, +196,194,192,252,80,144,44,8,35,42,2,37,2,71,22,153,8,198,199,249,247, +22,176,5,23,195,1,11,249,247,22,176,5,194,11,28,248,22,88,23,195,2, +9,27,27,248,22,81,23,197,2,28,248,22,134,16,23,194,2,248,22,137,16, +23,194,1,28,248,22,133,16,23,194,2,90,144,42,11,89,146,42,39,11,248, +22,130,16,249,22,135,16,250,80,144,50,43,42,248,22,150,16,2,56,11,11, +248,22,150,16,2,57,86,95,23,195,1,23,194,1,248,22,137,16,249,22,135, +16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,150,16,2,56,23, +197,1,10,28,23,193,2,248,22,137,16,23,194,1,11,28,23,193,2,249,22, +80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,27,248,22,162,20, +23,199,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81, +23,196,2,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1, +247,22,151,16,248,80,144,47,8,50,42,248,22,162,20,23,198,1,86,94,23, +193,1,248,80,144,45,8,50,42,248,22,162,20,23,196,1,86,94,23,193,1, +27,248,22,162,20,23,197,1,28,248,22,88,23,194,2,9,27,248,80,144,43, +56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,137,16,249,22, +135,16,23,198,1,247,22,151,16,248,80,144,45,8,50,42,248,22,162,20,23, +198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,162,20,23,196,1, +28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,134,16, +23,194,2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42, +11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,50,43,42,248, +22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1, +248,22,137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,45,43,42, +248,22,150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1, +11,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22, +151,16,27,248,22,162,20,23,199,1,28,248,22,88,23,194,2,9,27,248,80, +144,45,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,137,16, +249,22,135,16,23,198,1,247,22,151,16,248,80,144,47,8,51,42,248,22,162, +20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,162,20,23, +196,1,86,94,23,193,1,27,248,22,162,20,23,197,1,28,248,22,88,23,194, +2,9,27,248,80,144,43,56,42,248,22,81,23,196,2,28,23,193,2,249,22, +80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248,80,144,45,8, +51,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42, +248,22,162,20,23,196,1,27,248,22,150,16,2,58,28,248,22,134,16,23,194, +2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42,11,89, +146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,49,43,42,248,22,150, +16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1,248,22, +137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, +150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1,11,28, +248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,134,16,23, +194,2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42,11, +89,146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,50,43,42,248,22, +150,16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1,248, +22,137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248, +22,150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1,11, +28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151, +16,27,248,22,162,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248,22, +81,23,196,2,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248, +22,133,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22, +135,16,250,80,144,54,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2, +57,86,95,23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23, +196,1,27,250,80,144,49,43,42,248,22,150,16,2,56,23,197,1,10,28,23, +193,2,248,22,137,16,23,194,1,11,28,23,193,2,249,22,80,248,22,137,16, +249,22,135,16,23,198,1,247,22,151,16,27,248,22,162,20,23,198,1,28,248, +22,88,23,194,2,9,27,248,80,144,49,56,42,248,22,81,23,196,2,28,23, +193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248, +80,144,51,8,53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144, +49,8,53,42,248,22,162,20,23,196,1,86,94,23,193,1,27,248,22,162,20, +23,196,1,28,248,22,88,23,194,2,9,27,248,80,144,47,56,42,248,22,81, +23,196,2,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1, +247,22,151,16,248,80,144,49,8,53,42,248,22,162,20,23,198,1,86,94,23, +193,1,248,80,144,47,8,53,42,248,22,162,20,23,196,1,86,94,23,193,1, +27,248,22,162,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22,81, +23,196,2,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248,22, +133,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135, +16,250,80,144,52,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57, +86,95,23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23,196, +1,27,250,80,144,47,43,42,248,22,150,16,2,56,23,197,1,10,28,23,193, +2,248,22,137,16,23,194,1,11,28,23,193,2,249,22,80,248,22,137,16,249, +22,135,16,23,198,1,247,22,151,16,27,248,22,162,20,23,198,1,28,248,22, +88,23,194,2,9,27,248,80,144,47,56,42,248,22,81,23,196,2,28,23,193, +2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248,80, +144,49,8,53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144,47, +8,53,42,248,22,162,20,23,196,1,86,94,23,193,1,27,248,22,162,20,23, +196,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81,23, +196,2,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247, +22,151,16,248,80,144,47,8,53,42,248,22,162,20,23,198,1,86,94,23,193, +1,248,80,144,45,8,53,42,248,22,162,20,23,196,1,27,247,22,158,16,27, 248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44,41,28,23,196, -2,27,249,22,177,8,247,22,176,8,2,77,28,192,249,22,167,8,194,7,63, -2,68,2,68,250,80,144,46,8,23,42,23,198,2,2,78,27,28,23,200,1, -250,22,129,16,248,22,152,16,2,63,250,22,160,2,23,205,1,2,61,247,22, -173,8,2,79,86,94,23,199,1,11,27,248,80,144,49,8,51,42,250,22,96, -23,207,1,248,22,92,248,22,152,16,2,57,9,28,193,249,22,82,195,194,192, -27,247,22,160,16,27,248,80,144,42,58,42,249,80,144,44,55,40,40,80,144, -44,8,52,42,249,80,144,43,44,41,28,23,196,2,27,249,22,177,8,247,22, -176,8,2,77,28,192,249,22,167,8,194,7,63,2,68,2,68,250,80,144,46, -8,23,42,23,198,2,2,78,27,28,23,200,1,250,22,129,16,248,22,152,16, -2,63,250,22,160,2,23,205,1,2,61,247,22,173,8,2,79,86,94,23,199, -1,11,27,27,250,22,96,23,207,1,248,22,92,248,22,152,16,2,57,23,208, -1,28,248,22,90,23,194,2,9,27,27,248,22,83,23,196,2,28,248,22,136, -16,23,194,2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2,90,144, -42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,60,43,42, -248,22,152,16,2,58,11,11,248,22,152,16,2,59,86,95,23,195,1,23,194, -1,248,22,139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144,55,43, -42,248,22,152,16,2,58,23,197,1,10,28,23,193,2,248,22,139,16,23,194, -1,11,28,23,193,2,249,22,82,248,22,139,16,249,22,137,16,23,198,1,247, -22,153,16,27,248,22,164,20,23,198,1,28,248,22,90,23,194,2,9,27,248, -80,144,55,56,42,248,22,83,23,196,2,28,23,193,2,249,22,82,248,22,139, -16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,57,8,53,42,248,22, -164,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42,248,22,164,20, -23,196,1,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248,22,90,23, -194,2,9,27,248,80,144,53,56,42,248,22,83,23,196,2,28,23,193,2,249, -22,82,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,55, -8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144,53,8,53, -42,248,22,164,20,23,196,1,28,193,249,22,82,195,194,192,27,20,13,144,80, -144,40,46,40,26,9,80,144,49,47,40,249,22,33,11,80,144,51,46,40,22, -149,15,10,22,156,15,10,22,157,15,10,22,158,15,10,248,22,150,6,23,196, -2,28,248,22,150,7,23,194,2,12,86,94,248,22,179,9,23,194,1,27,20, -13,144,80,144,41,46,40,26,9,80,144,50,47,40,249,22,33,11,80,144,52, -46,40,22,149,15,10,22,156,15,10,22,157,15,10,22,158,15,10,248,22,150, -6,23,197,2,28,248,22,150,7,23,194,2,12,86,94,248,22,179,9,23,194, -1,27,20,13,144,80,144,42,46,40,26,9,80,144,51,47,40,249,22,33,11, -80,144,53,46,40,22,149,15,10,22,156,15,10,22,157,15,10,22,158,15,10, -248,22,150,6,23,198,2,28,248,22,150,7,23,194,2,12,86,94,248,22,179, -9,23,194,1,248,80,144,43,8,54,42,197,86,94,249,22,141,7,247,22,174, -5,23,196,2,248,22,165,6,249,22,138,4,39,249,22,186,3,28,23,198,2, -23,198,1,86,94,23,198,1,39,23,199,1,27,248,22,191,5,28,23,198,2, -86,95,23,197,1,23,196,1,23,198,1,86,94,23,198,1,27,250,80,144,45, -43,42,248,22,152,16,2,58,11,11,27,248,22,141,4,23,199,1,27,28,23, -194,2,23,194,1,86,94,23,194,1,39,27,248,22,141,4,23,202,1,249,22, -142,6,23,198,1,20,20,95,88,148,8,36,39,51,11,9,224,3,2,33,128, -3,23,195,1,23,196,1,248,80,144,41,8,54,42,193,144,39,20,120,145,2, -1,39,16,1,11,16,0,20,26,15,56,9,2,2,2,2,29,11,11,11,11, -11,11,11,9,9,11,11,11,10,46,80,143,39,39,20,120,145,2,1,54,16, -40,2,3,2,4,2,5,2,6,2,7,2,8,2,9,30,2,12,1,20,112, -97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,11,6, -30,2,12,1,23,101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114, -105,122,97,116,105,111,110,11,4,2,13,2,14,2,15,2,16,2,17,2,18, -2,19,30,2,20,1,19,99,97,99,104,101,45,99,111,110,102,105,103,117,114, -97,116,105,111,110,11,1,2,21,2,22,2,23,2,24,2,25,2,26,2,27, -2,28,2,29,2,30,2,31,30,2,20,1,21,101,120,99,101,112,116,105,111, -110,45,104,97,110,100,108,101,114,45,107,101,121,11,3,2,32,2,33,2,34, -2,35,2,36,2,37,2,38,2,39,2,40,2,41,2,42,16,0,40,42,39, -16,0,39,16,19,2,14,2,15,2,13,2,27,2,4,2,37,2,25,2,26, -2,21,2,31,2,35,2,23,2,24,2,33,2,29,2,32,2,34,2,38,2, -30,58,11,11,11,16,17,2,9,2,18,2,16,2,42,2,17,2,7,2,28, -2,41,2,19,2,22,2,40,2,5,2,36,2,8,2,39,2,3,2,6,16, -17,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,16,17,2, -9,2,18,2,16,2,42,2,17,2,7,2,28,2,41,2,19,2,22,2,40, -2,5,2,36,2,8,2,39,2,3,2,6,56,56,40,12,11,11,16,0,16, -0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,51,20,15, -16,2,32,0,88,148,8,36,40,48,11,2,3,222,33,80,80,144,39,39,40, -20,15,16,2,249,22,157,7,7,92,7,92,80,144,39,40,40,20,15,16,2, -88,148,8,36,40,57,41,2,5,223,0,33,85,80,144,39,41,40,20,15,16, -2,88,148,8,36,41,61,41,2,6,223,0,33,87,80,144,39,42,40,20,15, -16,2,20,25,96,2,7,88,148,8,36,42,8,24,8,32,9,223,0,33,94, -88,148,8,36,41,50,55,9,223,0,33,95,88,148,8,36,40,49,55,9,223, -0,33,96,80,144,39,43,40,20,15,16,2,27,248,22,164,16,248,22,169,8, -27,28,249,22,171,9,247,22,182,8,2,45,6,1,1,59,6,1,1,58,250, -22,139,8,6,14,14,40,91,94,126,97,93,42,41,126,97,40,46,42,41,23, -196,2,23,196,1,88,148,8,36,41,51,11,2,8,223,0,33,100,80,144,39, -44,40,20,15,16,2,88,148,39,40,8,38,8,128,6,2,9,223,0,33,101, -80,144,39,45,40,20,15,16,2,32,0,88,148,8,36,41,50,11,2,13,222, -33,102,80,144,39,48,40,20,15,16,2,32,0,88,148,8,36,42,51,11,2, -14,222,33,104,80,144,39,49,40,20,15,16,2,32,0,88,148,8,36,41,49, -11,2,15,222,33,105,80,144,39,50,40,20,15,16,2,88,148,39,42,53,8, -128,128,2,16,223,0,33,107,80,144,39,51,40,20,15,16,2,88,148,39,44, -55,8,128,128,2,18,223,0,33,109,80,144,39,53,40,20,15,16,2,88,148, -39,39,56,55,9,223,0,33,110,80,144,39,8,40,42,20,15,16,2,88,148, -39,39,47,16,4,39,40,8,128,4,39,2,19,223,0,33,111,80,144,39,54, -40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,112,80,144,39,8,41, -42,20,15,16,2,88,148,39,39,47,16,4,39,40,8,128,8,39,2,22,223, -0,33,113,80,144,39,57,40,20,15,16,2,88,148,8,36,39,8,38,8,128, -6,9,223,0,33,114,80,144,39,8,42,42,20,15,16,2,88,148,8,36,40, -50,16,4,39,39,8,128,16,39,2,23,223,0,33,115,80,144,39,58,40,20, -15,16,2,20,27,143,32,0,88,148,39,40,48,11,2,24,222,33,116,32,0, -88,148,39,40,48,11,2,24,222,33,117,80,144,39,59,40,20,15,16,2,88, -148,8,36,40,50,8,240,0,128,0,0,2,25,223,0,33,118,80,144,39,60, -40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,119,80,144,39,8,43, -42,20,15,16,2,88,148,8,36,40,51,16,4,39,40,8,128,32,39,2,26, -223,0,33,120,80,144,39,61,40,20,15,16,2,88,148,39,40,56,55,2,21, -223,0,33,121,80,144,39,56,40,20,15,16,2,88,148,8,36,41,58,16,4, -8,240,0,128,0,0,8,32,8,128,64,39,2,52,223,0,33,122,80,144,39, -8,44,42,20,15,16,2,88,148,8,36,42,52,16,4,39,39,8,128,64,39, -2,27,223,0,33,123,80,144,39,8,23,40,20,15,16,2,88,148,39,39,56, -55,9,223,0,33,124,80,144,39,8,45,42,20,15,16,2,88,148,8,36,39, -57,16,4,8,240,0,128,0,0,8,137,2,8,128,128,39,2,28,223,0,33, -125,80,144,39,8,24,40,20,15,16,2,247,22,142,2,80,144,39,8,25,40, -20,15,16,2,248,22,18,67,115,116,97,109,112,80,144,39,8,26,40,20,15, -16,2,88,148,39,40,49,8,240,0,0,0,4,9,223,0,33,127,80,144,39, -8,46,42,20,15,16,2,88,148,39,41,51,16,4,39,8,128,80,8,240,0, -64,0,0,39,2,31,223,0,33,135,2,80,144,39,8,27,40,20,15,16,2, -32,0,88,148,8,36,40,48,11,2,32,222,33,136,2,80,144,39,8,29,40, -20,15,16,2,88,148,8,36,42,48,8,240,0,0,0,2,74,109,97,107,101, -45,104,97,110,100,108,101,114,223,0,33,138,2,80,144,39,8,47,42,20,15, -16,2,88,148,39,40,47,16,4,8,128,6,8,128,104,8,240,0,128,0,0, -39,2,33,223,0,33,148,2,80,144,39,8,30,40,20,15,16,2,88,148,39, -41,59,16,2,39,8,240,0,128,0,0,2,34,223,0,33,150,2,80,144,39, -8,31,40,20,15,16,2,88,148,8,36,41,61,16,4,39,8,240,0,64,0, -0,39,40,2,52,223,0,33,151,2,80,144,39,8,48,42,20,15,16,2,88, -148,39,47,8,33,16,4,39,39,40,41,67,99,108,111,111,112,223,0,33,158, -2,80,144,39,8,49,42,20,15,16,2,88,148,39,44,8,25,16,4,39,8, -240,0,192,0,0,39,42,2,17,223,0,33,159,2,80,144,39,52,40,20,15, -16,2,88,148,39,42,58,16,4,47,39,43,39,2,35,223,0,33,164,2,80, -144,39,8,32,40,20,15,16,2,32,0,88,148,39,42,53,11,2,37,222,33, -165,2,80,144,39,8,34,40,20,15,16,2,32,0,88,148,8,36,44,8,27, -11,2,38,222,33,170,2,80,144,39,8,35,40,20,15,16,2,20,27,143,32, -0,88,148,8,36,41,55,11,2,39,222,33,173,2,88,148,8,100,41,52,16, -4,39,39,47,39,2,39,223,0,33,175,2,80,144,39,8,36,40,20,15,16, -2,20,27,143,32,0,88,148,8,36,41,55,11,2,36,222,33,180,2,88,148, -8,100,41,52,16,4,39,39,47,39,2,36,223,0,33,181,2,80,144,39,8, -33,40,20,15,16,2,20,27,143,32,0,88,148,39,40,47,11,2,40,222,33, -182,2,32,0,88,148,39,40,47,11,2,40,222,33,183,2,80,144,39,8,37, -40,20,15,16,2,88,148,8,36,40,58,16,4,55,41,39,43,2,52,223,0, -33,184,2,80,144,39,8,50,42,20,15,16,2,88,148,8,36,40,58,16,4, -55,41,39,47,2,52,223,0,33,185,2,80,144,39,8,51,42,20,15,16,2, -88,148,39,39,56,55,9,223,0,33,186,2,80,144,39,8,52,42,20,15,16, -2,88,148,8,36,40,8,23,16,4,55,41,39,8,32,2,52,223,0,33,187, -2,80,144,39,8,53,42,20,15,16,2,20,25,96,2,41,88,148,39,39,60, -16,4,8,32,8,140,2,39,43,9,223,0,33,188,2,88,148,39,40,61,16, -4,8,32,8,140,2,39,47,9,223,0,33,189,2,88,148,39,41,8,30,16, -4,8,48,8,139,2,39,8,48,9,223,0,33,190,2,80,144,39,8,38,40, -20,15,16,2,88,148,8,36,40,60,16,4,8,128,6,39,39,8,64,2,52, -223,0,33,191,2,80,144,39,8,54,42,20,15,16,2,88,148,8,36,42,56, -16,4,55,39,39,8,64,2,42,223,0,33,129,3,80,144,39,8,39,40,95, -29,94,2,10,70,35,37,107,101,114,110,101,108,11,29,94,2,10,71,35,37, -109,105,110,45,115,116,120,11,2,20,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 19776); +2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63, +2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1, +250,22,191,15,248,22,150,16,2,61,250,22,158,2,23,205,1,2,59,247,22, +171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,50,42,250,22,94, +9,248,22,90,248,22,150,16,2,55,9,28,193,249,22,80,195,194,192,27,247, +22,158,16,27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44, +41,28,23,196,2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165, +8,194,7,63,2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27, +28,23,200,1,250,22,191,15,248,22,150,16,2,61,250,22,158,2,23,205,1, +2,59,247,22,171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,51, +42,250,22,94,23,207,1,248,22,90,248,22,150,16,2,55,9,28,193,249,22, +80,195,194,192,27,247,22,158,16,27,248,80,144,42,58,42,249,80,144,44,55, +40,40,80,144,44,8,52,42,249,80,144,43,44,41,28,23,196,2,27,249,22, +175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63,2,66,2,66, +250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1,250,22,191,15, +248,22,150,16,2,61,250,22,158,2,23,205,1,2,59,247,22,171,8,2,77, +86,94,23,199,1,11,27,27,250,22,94,23,207,1,248,22,90,248,22,150,16, +2,55,23,208,1,28,248,22,88,23,194,2,9,27,27,248,22,81,23,196,2, +28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248,22,133,16,23, +194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80, +144,60,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23, +195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23,196,1,27,250, +80,144,55,43,42,248,22,150,16,2,56,23,197,1,10,28,23,193,2,248,22, +137,16,23,194,1,11,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16, +23,198,1,247,22,151,16,27,248,22,162,20,23,198,1,28,248,22,88,23,194, +2,9,27,248,80,144,55,56,42,248,22,81,23,196,2,28,23,193,2,249,22, +80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248,80,144,57,8, +53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42, +248,22,162,20,23,196,1,86,94,23,193,1,27,248,22,162,20,23,196,1,28, +248,22,88,23,194,2,9,27,248,80,144,53,56,42,248,22,81,23,196,2,28, +23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16, +248,80,144,55,8,53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80, +144,53,8,53,42,248,22,162,20,23,196,1,28,193,249,22,80,195,194,192,27, +20,13,144,80,144,40,46,40,26,9,80,144,49,47,40,249,22,31,11,80,144, +51,46,40,22,147,15,10,22,154,15,10,22,155,15,10,22,156,15,10,248,22, +148,6,23,196,2,28,248,22,148,7,23,194,2,12,86,94,248,22,177,9,23, +194,1,27,20,13,144,80,144,41,46,40,26,9,80,144,50,47,40,249,22,31, +11,80,144,52,46,40,22,147,15,10,22,154,15,10,22,155,15,10,22,156,15, +10,248,22,148,6,23,197,2,28,248,22,148,7,23,194,2,12,86,94,248,22, +177,9,23,194,1,27,20,13,144,80,144,42,46,40,26,9,80,144,51,47,40, +249,22,31,11,80,144,53,46,40,22,147,15,10,22,154,15,10,22,155,15,10, +22,156,15,10,248,22,148,6,23,198,2,28,248,22,148,7,23,194,2,12,86, +94,248,22,177,9,23,194,1,248,80,144,43,8,54,42,197,86,94,249,22,139, +7,247,22,172,5,23,196,2,248,22,163,6,249,22,136,4,39,249,22,184,3, +28,23,198,2,23,198,1,86,94,23,198,1,39,23,199,1,27,248,22,189,5, +28,23,198,2,86,95,23,197,1,23,196,1,23,198,1,86,94,23,198,1,27, +250,80,144,45,43,42,248,22,150,16,2,56,11,11,27,248,22,139,4,23,199, +1,27,28,23,194,2,23,194,1,86,94,23,194,1,39,27,248,22,139,4,23, +202,1,249,22,140,6,23,198,1,20,20,95,88,148,8,36,39,51,11,9,224, +3,2,33,190,2,23,195,1,23,196,1,248,80,144,41,8,54,42,193,144,39, +20,121,145,2,1,39,16,1,11,16,0,20,27,15,56,9,2,2,2,2,29, +11,11,11,11,11,11,11,9,9,11,11,11,10,46,80,143,39,39,20,121,145, +2,1,54,16,40,2,3,2,4,2,5,2,6,2,7,2,8,2,9,30,2, +11,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107, +101,121,11,6,30,2,11,1,23,101,120,116,101,110,100,45,112,97,114,97,109, +101,116,101,114,105,122,97,116,105,111,110,11,4,2,12,2,13,2,14,2,15, +2,16,2,17,2,18,30,2,11,1,19,99,97,99,104,101,45,99,111,110,102, +105,103,117,114,97,116,105,111,110,11,1,2,19,2,20,2,21,2,22,2,23, +2,24,2,25,2,26,2,27,2,28,2,29,30,2,11,1,21,101,120,99,101, +112,116,105,111,110,45,104,97,110,100,108,101,114,45,107,101,121,11,3,2,30, +2,31,2,32,2,33,2,34,2,35,2,36,2,37,2,38,2,39,2,40,16, +0,40,42,39,16,0,39,16,19,2,13,2,14,2,12,2,25,2,4,2,35, +2,23,2,24,2,19,2,29,2,33,2,21,2,22,2,31,2,27,2,30,2, +32,2,36,2,28,58,11,11,11,16,17,2,9,2,17,2,15,2,40,2,16, +2,7,2,26,2,39,2,18,2,20,2,38,2,5,2,34,2,8,2,37,2, +3,2,6,16,17,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +11,16,17,2,9,2,17,2,15,2,40,2,16,2,7,2,26,2,39,2,18, +2,20,2,38,2,5,2,34,2,8,2,37,2,3,2,6,56,56,40,12,11, +11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39, +16,51,20,15,16,2,32,0,88,148,8,36,40,48,11,2,3,222,33,78,80, +144,39,39,40,20,15,16,2,249,22,155,7,7,92,7,92,80,144,39,40,40, +20,15,16,2,88,148,8,36,40,57,41,2,5,223,0,33,83,80,144,39,41, +40,20,15,16,2,88,148,8,36,41,61,41,2,6,223,0,33,85,80,144,39, +42,40,20,15,16,2,20,26,96,2,7,88,148,8,36,42,8,24,8,32,9, +223,0,33,92,88,148,8,36,41,50,55,9,223,0,33,93,88,148,8,36,40, +49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,162,16, +248,22,167,8,27,28,249,22,169,9,247,22,180,8,2,43,6,1,1,59,6, +1,1,58,250,22,137,8,6,14,14,40,91,94,126,97,93,42,41,126,97,40, +46,42,41,23,196,2,23,196,1,88,148,8,36,41,51,11,2,8,223,0,33, +98,80,144,39,44,40,20,15,16,2,88,148,39,40,8,38,8,128,6,2,9, +223,0,33,99,80,144,39,45,40,20,15,16,2,32,0,88,148,8,36,41,50, +11,2,12,222,33,100,80,144,39,48,40,20,15,16,2,32,0,88,148,8,36, +42,51,11,2,13,222,33,102,80,144,39,49,40,20,15,16,2,32,0,88,148, +8,36,41,49,11,2,14,222,33,103,80,144,39,50,40,20,15,16,2,88,148, +39,42,53,8,128,128,2,15,223,0,33,105,80,144,39,51,40,20,15,16,2, +88,148,39,44,55,8,128,128,2,17,223,0,33,107,80,144,39,53,40,20,15, +16,2,88,148,39,39,56,55,9,223,0,33,108,80,144,39,8,40,42,20,15, +16,2,88,148,39,39,47,16,4,39,40,8,128,4,39,2,18,223,0,33,109, +80,144,39,54,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,110,80, +144,39,8,41,42,20,15,16,2,88,148,39,39,47,16,4,39,40,8,128,8, +39,2,20,223,0,33,111,80,144,39,57,40,20,15,16,2,88,148,8,36,39, +8,38,8,128,6,9,223,0,33,112,80,144,39,8,42,42,20,15,16,2,88, +148,8,36,40,50,16,4,39,39,8,128,16,39,2,21,223,0,33,113,80,144, +39,58,40,20,15,16,2,20,28,143,32,0,88,148,39,40,48,11,2,22,222, +33,114,32,0,88,148,39,40,48,11,2,22,222,33,115,80,144,39,59,40,20, +15,16,2,88,148,8,36,40,50,8,240,0,128,0,0,2,23,223,0,33,116, +80,144,39,60,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,117,80, +144,39,8,43,42,20,15,16,2,88,148,8,36,40,51,16,4,39,40,8,128, +32,39,2,24,223,0,33,118,80,144,39,61,40,20,15,16,2,88,148,39,40, +56,55,2,19,223,0,33,119,80,144,39,56,40,20,15,16,2,88,148,8,36, +41,58,16,4,8,240,0,128,0,0,8,32,8,128,64,39,2,50,223,0,33, +120,80,144,39,8,44,42,20,15,16,2,88,148,8,36,42,52,16,4,39,39, +8,128,64,39,2,25,223,0,33,121,80,144,39,8,23,40,20,15,16,2,88, +148,39,39,56,55,9,223,0,33,122,80,144,39,8,45,42,20,15,16,2,88, +148,8,36,39,57,16,4,8,240,0,128,0,0,8,137,2,8,128,128,39,2, +26,223,0,33,123,80,144,39,8,24,40,20,15,16,2,247,22,140,2,80,144, +39,8,25,40,20,15,16,2,248,22,16,67,115,116,97,109,112,80,144,39,8, +26,40,20,15,16,2,88,148,39,40,49,8,240,0,0,0,4,9,223,0,33, +125,80,144,39,8,46,42,20,15,16,2,88,148,39,41,51,16,4,39,8,128, +80,8,240,0,64,0,0,39,2,29,223,0,33,133,2,80,144,39,8,27,40, +20,15,16,2,32,0,88,148,8,36,40,48,11,2,30,222,33,134,2,80,144, +39,8,29,40,20,15,16,2,88,148,8,36,42,48,8,240,0,0,0,2,74, +109,97,107,101,45,104,97,110,100,108,101,114,223,0,33,136,2,80,144,39,8, +47,42,20,15,16,2,88,148,39,40,47,16,4,8,128,6,8,128,104,8,240, +0,128,0,0,39,2,31,223,0,33,146,2,80,144,39,8,30,40,20,15,16, +2,88,148,39,41,59,16,2,39,8,240,0,128,0,0,2,32,223,0,33,148, +2,80,144,39,8,31,40,20,15,16,2,88,148,8,36,41,61,16,4,39,8, +240,0,64,0,0,39,40,2,50,223,0,33,149,2,80,144,39,8,48,42,20, +15,16,2,88,148,39,47,8,33,16,4,39,39,40,41,67,99,108,111,111,112, +223,0,33,156,2,80,144,39,8,49,42,20,15,16,2,88,148,39,44,8,25, +16,4,39,8,240,0,192,0,0,39,42,2,16,223,0,33,157,2,80,144,39, +52,40,20,15,16,2,88,148,39,42,58,16,4,47,39,43,39,2,33,223,0, +33,162,2,80,144,39,8,32,40,20,15,16,2,32,0,88,148,39,42,53,11, +2,35,222,33,163,2,80,144,39,8,34,40,20,15,16,2,32,0,88,148,8, +36,44,8,27,11,2,36,222,33,168,2,80,144,39,8,35,40,20,15,16,2, +20,28,143,32,0,88,148,8,36,41,55,11,2,37,222,33,171,2,88,148,8, +100,41,52,16,4,39,39,47,39,2,37,223,0,33,173,2,80,144,39,8,36, +40,20,15,16,2,20,28,143,32,0,88,148,8,36,41,55,11,2,34,222,33, +178,2,88,148,8,100,41,52,16,4,39,39,47,39,2,34,223,0,33,179,2, +80,144,39,8,33,40,20,15,16,2,20,28,143,32,0,88,148,39,40,47,11, +2,38,222,33,180,2,32,0,88,148,39,40,47,11,2,38,222,33,181,2,80, +144,39,8,37,40,20,15,16,2,88,148,8,36,40,58,16,4,55,41,39,43, +2,50,223,0,33,182,2,80,144,39,8,50,42,20,15,16,2,88,148,8,36, +40,58,16,4,55,41,39,47,2,50,223,0,33,183,2,80,144,39,8,51,42, +20,15,16,2,88,148,39,39,56,55,9,223,0,33,184,2,80,144,39,8,52, +42,20,15,16,2,88,148,8,36,40,8,23,16,4,55,41,39,8,32,2,50, +223,0,33,185,2,80,144,39,8,53,42,20,15,16,2,20,26,96,2,39,88, +148,39,39,60,16,4,8,32,8,140,2,39,43,9,223,0,33,186,2,88,148, +39,40,61,16,4,8,32,8,140,2,39,47,9,223,0,33,187,2,88,148,39, +41,8,30,16,4,8,48,8,139,2,39,8,48,9,223,0,33,188,2,80,144, +39,8,38,40,20,15,16,2,88,148,8,36,40,60,16,4,8,128,6,39,39, +8,64,2,50,223,0,33,189,2,80,144,39,8,54,42,20,15,16,2,88,148, +8,36,42,56,16,4,55,39,39,8,64,2,40,223,0,33,191,2,80,144,39, +8,39,40,95,29,94,2,10,70,35,37,107,101,114,110,101,108,11,29,94,2, +10,71,35,37,109,105,110,45,115,116,120,11,2,11,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 19759); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,54,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,8,0, 23,0,48,0,65,0,83,0,105,0,128,0,149,0,171,0,180,0,189,0,196, 0,205,0,212,0,0,0,247,1,0,0,3,1,5,105,110,115,112,48,76,35, @@ -1060,516 +1059,515 @@ 99,101,45,99,104,97,110,110,101,108,45,105,110,1,20,84,72,45,112,108,97, 99,101,45,99,104,97,110,110,101,108,45,111,117,116,249,80,143,41,42,23,196, 1,39,249,80,143,41,42,23,196,1,39,249,80,143,41,42,195,39,249,80,143, -41,42,23,196,1,40,249,80,143,41,42,195,40,144,39,20,120,145,2,1,39, -16,1,11,16,0,20,26,15,56,9,2,2,2,2,29,11,11,11,11,11,11, -11,9,9,11,11,11,10,48,80,143,39,39,20,120,145,2,1,39,16,7,2, +41,42,23,196,1,40,249,80,143,41,42,195,40,144,39,20,121,145,2,1,39, +16,1,11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11, +11,9,9,11,11,11,10,48,80,143,39,39,20,121,145,2,1,39,16,7,2, 3,2,4,2,5,2,6,2,7,2,8,2,9,16,0,40,42,39,16,0,39, 16,2,2,6,2,7,41,11,11,11,16,5,2,4,2,8,2,9,2,5,2, 3,16,5,11,11,11,11,11,16,5,2,4,2,8,2,9,2,5,2,3,44, 44,40,12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0, -16,0,39,39,16,3,20,15,16,6,253,22,190,10,2,4,11,41,39,11,248, -22,92,249,22,82,22,176,10,88,148,39,40,48,47,9,223,9,33,10,80,144, +16,0,39,39,16,3,20,15,16,6,253,22,188,10,2,4,11,41,39,11,248, +22,90,249,22,80,22,174,10,88,148,39,40,48,47,9,223,9,33,10,80,144, 39,39,40,80,144,39,40,40,80,144,39,41,40,80,144,39,42,40,80,144,39, -43,40,20,15,16,2,20,27,143,88,148,39,40,48,47,9,223,0,33,11,88, -148,39,40,48,47,9,223,0,33,12,80,144,39,44,40,20,15,16,2,20,27, +43,40,20,15,16,2,20,28,143,88,148,39,40,48,47,9,223,0,33,11,88, +148,39,40,48,47,9,223,0,33,12,80,144,39,44,40,20,15,16,2,20,28, 143,88,148,39,40,48,47,9,223,0,33,13,88,148,39,40,48,47,9,223,0, 33,14,80,144,39,45,40,93,29,94,67,113,117,111,116,101,70,35,37,107,101, 114,110,101,108,11,9,9,9,39,9,0}; EVAL_ONE_SIZED_STR((char *)expr, 577); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,54,84,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,103,0,0,0,1,0,0,8,0, -15,0,26,0,53,0,59,0,68,0,75,0,97,0,110,0,136,0,153,0,175, -0,183,0,195,0,210,0,226,0,244,0,9,1,21,1,37,1,60,1,84,1, -96,1,127,1,134,1,139,1,144,1,162,1,168,1,173,1,182,1,187,1,193, -1,198,1,202,1,217,1,224,1,229,1,233,1,238,1,245,1,0,2,7,2, -15,2,118,2,153,2,0,3,35,3,129,3,164,3,2,4,37,4,38,11,68, -11,119,11,194,11,210,11,226,11,240,11,0,12,75,12,91,12,107,12,123,12, -198,12,105,13,121,13,196,13,191,14,71,15,146,15,53,16,66,16,219,16,147, -17,190,17,16,18,144,18,206,18,214,18,225,18,3,20,106,20,134,20,147,20, -68,21,75,21,235,21,255,21,99,22,121,22,131,22,145,22,183,22,26,23,30, -23,37,23,243,23,137,32,190,32,214,32,238,32,0,0,17,37,0,0,3,1, -5,105,110,115,112,48,68,35,37,98,111,111,116,72,100,108,108,45,115,117,102, -102,105,120,1,25,100,101,102,97,117,108,116,45,108,111,97,100,47,117,115,101, -45,99,111,109,112,105,108,101,100,67,113,117,111,116,101,70,35,37,112,97,114, -97,109,122,29,94,2,5,2,6,11,1,20,112,97,114,97,109,101,116,101,114, -105,122,97,116,105,111,110,45,107,101,121,29,94,2,5,69,35,37,117,116,105, -108,115,11,1,24,45,109,111,100,117,108,101,45,104,97,115,104,45,116,97,98, -108,101,45,116,97,98,108,101,78,114,101,103,105,115,116,101,114,45,122,111,45, -112,97,116,104,1,20,100,101,102,97,117,108,116,45,114,101,97,100,101,114,45, -103,117,97,114,100,69,67,65,67,72,69,45,78,73,45,112,97,116,104,45,99, -97,99,104,101,76,112,97,116,104,45,99,97,99,104,101,45,103,101,116,77,112, -97,116,104,45,99,97,99,104,101,45,115,101,116,33,79,45,108,111,97,100,105, -110,103,45,102,105,108,101,110,97,109,101,1,19,45,108,111,97,100,105,110,103, -45,112,114,111,109,112,116,45,116,97,103,73,45,112,114,101,118,45,114,101,108, -116,111,77,45,112,114,101,118,45,114,101,108,116,111,45,100,105,114,1,21,115, -112,108,105,116,45,114,101,108,97,116,105,118,101,45,115,116,114,105,110,103,1, -22,102,111,114,109,97,116,45,115,111,117,114,99,101,45,108,111,99,97,116,105, -111,110,73,111,114,105,103,45,112,97,114,97,109,122,1,29,115,116,97,110,100, -97,114,100,45,109,111,100,117,108,101,45,110,97,109,101,45,114,101,115,111,108, -118,101,114,29,94,2,5,2,6,11,66,98,111,111,116,66,115,101,97,108,79, -108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,5,4,46,114, -107,116,66,115,97,109,101,6,6,6,110,97,116,105,118,101,5,3,46,122,111, -67,105,108,111,111,112,66,108,111,111,112,65,108,105,98,6,12,12,109,111,100, -117,108,101,45,112,97,116,104,63,68,115,117,98,109,111,100,6,2,2,46,46, -6,1,1,46,66,102,105,108,101,68,112,108,97,110,101,116,6,8,8,109,97, -105,110,46,114,107,116,6,4,4,46,114,107,116,69,105,103,110,111,114,101,100, -27,252,22,129,16,28,249,22,171,9,23,201,2,2,30,86,94,23,199,1,23, -200,1,28,248,22,134,16,23,200,2,249,22,129,16,23,202,1,23,201,1,249, -80,144,50,45,42,23,202,1,23,201,1,23,203,1,2,31,247,22,183,8,249, -80,144,50,46,42,23,203,1,80,144,50,39,41,27,250,22,147,16,196,11,32, -0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,82,195,194,11,249,22, -5,20,20,96,88,148,8,36,40,57,8,129,3,9,226,5,4,3,6,33,45, -23,199,1,23,196,1,23,197,1,23,195,1,27,252,22,129,16,28,249,22,171, -9,23,201,2,2,30,86,94,23,199,1,23,200,1,28,248,22,134,16,23,200, -2,249,22,129,16,23,202,1,23,201,1,249,80,144,50,45,42,23,202,1,23, -201,1,23,203,1,2,31,247,22,183,8,249,80,144,50,46,42,23,203,1,80, -144,50,39,41,27,250,22,147,16,196,11,32,0,88,148,8,36,39,44,11,9, -222,11,28,192,249,22,82,195,194,11,249,22,5,20,20,96,88,148,8,36,40, -57,8,129,3,9,226,5,4,3,6,33,47,23,199,1,23,196,1,23,197,1, -23,195,1,27,250,22,129,16,28,249,22,171,9,23,199,2,2,30,86,94,23, -197,1,23,198,1,28,248,22,134,16,23,198,2,249,22,129,16,23,200,1,23, -199,1,249,80,144,48,45,42,23,200,1,23,199,1,23,201,1,249,80,144,48, -46,42,23,201,1,2,32,27,250,22,147,16,196,11,32,0,88,148,8,36,39, -44,11,9,222,11,28,192,249,22,82,195,194,11,249,22,5,20,20,96,88,148, -8,36,40,55,8,128,3,9,226,5,4,3,6,33,49,23,199,1,23,196,1, -23,197,1,23,195,1,27,250,22,129,16,28,249,22,171,9,23,199,2,2,30, -86,94,23,197,1,23,198,1,28,248,22,134,16,23,198,2,249,22,129,16,23, -200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23,201,1,249, -80,144,48,46,42,23,201,1,2,32,27,250,22,147,16,196,11,32,0,88,148, -8,36,39,44,11,9,222,11,28,192,249,22,82,195,194,11,249,22,5,20,20, -96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6,33,51,23,199,1, -23,196,1,23,197,1,23,195,1,86,95,28,248,80,144,40,43,42,23,195,2, -12,250,22,182,11,2,28,6,12,12,112,97,116,104,45,115,116,114,105,110,103, -63,23,197,2,28,28,23,195,2,28,248,22,66,23,196,2,10,28,248,22,91, -23,196,2,28,249,22,132,4,248,22,95,23,198,2,40,28,28,248,22,66,248, -22,83,23,197,2,10,248,22,169,9,248,22,163,20,23,197,2,249,22,4,22, -66,248,22,164,20,23,198,2,11,11,11,10,12,250,22,182,11,2,28,6,71, -71,40,111,114,47,99,32,35,102,32,115,121,109,98,111,108,63,32,40,99,111, -110,115,47,99,32,40,111,114,47,99,32,35,102,32,115,121,109,98,111,108,63, -41,32,40,110,111,110,45,101,109,112,116,121,45,108,105,115,116,111,102,32,115, -121,109,98,111,108,63,41,41,41,23,197,2,27,28,23,196,2,247,22,129,5, -11,27,28,23,194,2,250,22,160,2,80,143,44,44,248,22,129,17,247,22,145, -14,11,11,27,28,23,194,2,250,22,160,2,248,22,84,23,198,2,23,198,2, -11,11,28,23,193,2,86,96,23,197,1,23,195,1,23,194,1,20,13,144,80, -144,42,41,40,250,80,144,45,42,40,249,22,33,11,80,144,47,41,40,22,130, -5,248,22,104,23,197,2,27,248,22,113,23,195,2,20,13,144,80,144,43,41, -40,250,80,144,46,42,40,249,22,33,11,80,144,48,41,40,22,179,5,28,248, -22,175,15,23,197,2,23,196,1,86,94,23,196,1,247,22,153,16,249,247,22, -177,5,248,22,163,20,23,197,1,23,201,1,86,94,23,193,1,27,28,248,22, -136,16,23,199,2,23,198,2,27,247,22,179,5,28,192,249,22,137,16,23,201, -2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22,132,16,23,202,1, -86,94,23,195,1,90,144,41,11,89,146,41,39,11,28,23,204,2,27,248,22, -180,15,23,198,2,19,248,22,149,8,194,28,28,249,22,134,4,23,195,4,43, -249,22,152,8,2,29,249,22,155,8,197,249,22,186,3,23,199,4,43,11,249, -22,7,23,200,2,248,22,184,15,249,22,156,8,250,22,155,8,201,39,249,22, -186,3,23,203,4,43,5,3,46,115,115,249,22,7,23,200,2,11,2,249,22, -7,23,198,2,11,27,28,249,22,171,9,23,196,2,23,199,2,23,199,2,249, -22,129,16,23,198,2,23,196,2,27,28,23,196,2,28,249,22,171,9,23,198, -2,23,200,1,23,200,1,86,94,23,200,1,249,22,129,16,23,199,2,23,198, -2,86,94,23,198,1,11,27,28,249,22,171,9,23,200,2,70,114,101,108,97, -116,105,118,101,86,94,23,198,1,2,30,23,198,1,27,247,22,158,16,27,247, -22,159,16,27,250,22,147,16,23,201,2,11,32,0,88,148,8,36,39,44,11, -9,222,11,27,28,23,194,2,249,22,82,23,201,2,23,196,1,86,94,23,194, -1,11,27,28,23,199,2,28,23,194,2,11,27,250,22,147,16,23,203,2,11, -32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,82,23,202,2,194, -11,11,27,28,23,195,2,23,195,2,23,194,2,27,28,23,196,2,23,196,2, -248,22,169,9,23,196,2,27,28,23,205,2,28,23,196,2,86,94,23,197,1, -23,196,2,248,22,169,9,23,198,1,11,27,28,23,195,2,27,249,22,5,88, -148,39,40,51,8,129,3,9,226,24,15,12,11,33,46,23,203,2,27,28,23, -198,2,11,193,28,192,192,28,193,28,23,198,2,28,249,22,134,4,248,22,84, -196,248,22,84,23,201,2,193,11,11,11,11,28,23,193,2,86,105,23,213,1, -23,212,1,23,206,1,23,205,1,23,204,1,23,203,1,23,201,1,23,200,1, -23,197,1,23,196,1,23,195,1,23,194,1,20,13,144,80,144,60,41,40,250, -80,144,8,24,42,40,249,22,33,11,80,144,8,26,41,40,22,130,5,11,20, -13,144,80,144,60,41,40,250,80,144,8,24,42,40,249,22,33,11,80,144,8, -26,41,40,22,179,5,28,248,22,175,15,23,206,2,23,205,1,86,94,23,205, -1,247,22,153,16,249,247,22,163,16,248,22,83,23,196,1,23,218,1,86,94, -23,193,1,27,28,23,195,2,27,249,22,5,88,148,39,40,51,8,129,3,9, -226,25,17,13,12,33,48,23,204,2,27,28,23,200,2,11,193,28,192,192,28, -193,28,199,28,249,22,134,4,248,22,84,196,248,22,84,202,193,11,11,11,11, -28,23,193,2,86,103,23,214,1,23,213,1,23,207,1,23,206,1,23,205,1, -23,202,1,23,201,1,23,197,1,23,196,1,23,195,1,20,13,144,80,144,61, -41,40,250,80,144,8,25,42,40,249,22,33,11,80,144,8,27,41,40,22,130, -5,23,207,1,20,13,144,80,144,61,41,40,250,80,144,8,25,42,40,249,22, -33,11,80,144,8,27,41,40,22,179,5,28,248,22,175,15,23,207,2,23,206, -1,86,94,23,206,1,247,22,153,16,249,247,22,163,16,248,22,83,23,196,1, -23,219,1,86,94,23,193,1,27,28,23,197,2,27,249,22,5,20,20,94,88, -148,39,40,51,8,128,3,9,226,26,17,14,13,33,50,23,210,1,23,205,2, -27,28,23,200,2,11,193,28,192,192,28,193,28,23,200,2,28,249,22,134,4, -248,22,84,196,248,22,84,23,203,2,193,11,11,11,86,94,23,207,1,11,28, -23,193,2,86,101,23,208,1,23,206,1,23,205,1,23,203,1,23,202,1,23, -198,1,23,197,1,23,196,1,86,94,27,248,22,83,23,195,2,28,23,215,2, -250,22,158,2,248,22,84,23,219,1,23,219,1,250,22,92,23,199,1,11,23, -211,2,12,20,13,144,80,144,8,23,41,40,250,80,144,8,26,42,40,249,22, -33,11,80,144,8,28,41,40,22,130,5,11,20,13,144,80,144,8,23,41,40, -250,80,144,8,26,42,40,249,22,33,11,80,144,8,28,41,40,22,179,5,28, -248,22,175,15,23,208,2,23,207,1,86,94,23,207,1,247,22,153,16,249,247, -22,177,5,248,22,163,20,23,196,1,23,220,1,86,94,23,193,1,27,28,23, -197,1,27,249,22,5,20,20,95,88,148,39,40,51,8,128,3,9,226,27,19, -15,14,33,52,23,207,1,23,212,1,23,206,1,27,28,23,201,2,11,193,28, -192,192,28,193,28,200,28,249,22,134,4,248,22,84,196,248,22,84,203,193,11, -11,11,86,96,23,209,1,23,204,1,23,203,1,11,28,23,193,2,86,95,23, -207,1,23,198,1,86,94,27,248,22,83,23,195,2,28,23,216,2,250,22,158, -2,248,22,84,23,220,1,23,220,1,250,22,92,23,199,1,23,213,2,23,212, -2,12,20,13,144,80,144,8,24,41,40,250,80,144,8,27,42,40,249,22,33, -11,80,144,8,29,41,40,22,130,5,23,209,1,20,13,144,80,144,8,24,41, -40,250,80,144,8,27,42,40,249,22,33,11,80,144,8,29,41,40,22,179,5, -28,248,22,175,15,23,209,2,23,208,1,86,94,23,208,1,247,22,153,16,249, -247,22,177,5,248,22,163,20,23,196,1,23,221,1,86,94,23,193,1,28,28, -248,22,80,23,220,2,248,22,163,20,23,220,2,10,27,28,23,199,2,86,94, -23,207,1,23,208,1,86,94,23,208,1,23,207,1,28,28,248,22,80,23,221, -2,248,22,169,9,248,22,187,15,23,195,2,11,12,20,13,144,80,144,8,25, -41,40,250,80,144,8,28,42,40,249,22,33,11,80,144,8,30,41,40,22,130, -5,28,23,223,2,28,23,202,1,11,23,196,2,86,94,23,202,1,11,20,13, -144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22,33,11,80,144,8, -30,41,40,22,179,5,28,248,22,175,15,23,210,2,23,209,1,86,94,23,209, -1,247,22,153,16,249,247,22,177,5,23,195,1,23,222,1,12,28,23,194,2, -250,22,158,2,248,22,84,23,198,1,23,196,1,250,22,92,23,201,1,23,202, -1,23,203,1,12,27,249,22,191,8,80,144,42,50,41,249,22,129,4,248,22, -189,3,248,22,175,2,200,8,128,8,27,28,193,248,22,178,2,194,11,28,192, -27,249,22,102,198,195,28,192,248,22,84,193,11,11,27,249,22,129,4,248,22, -189,3,248,22,175,2,23,199,2,8,128,8,27,249,22,191,8,80,144,43,50, -41,23,196,2,250,22,128,9,80,144,44,50,41,23,197,1,248,22,177,2,249, -22,82,249,22,82,23,204,1,23,205,1,27,28,23,200,2,248,22,178,2,200, -11,28,192,192,9,32,57,88,149,8,38,42,54,11,2,33,39,223,3,33,72, -32,58,88,149,8,38,42,53,11,2,33,39,223,3,33,71,32,59,88,148,8, -36,40,53,11,2,34,222,33,70,32,60,88,149,8,38,42,53,11,2,33,39, -223,3,33,61,28,249,22,130,4,23,197,2,23,195,4,248,22,92,194,28,249, -22,138,9,7,47,249,22,159,7,23,198,2,23,199,2,249,22,82,250,22,177, -7,23,199,2,39,23,200,2,248,2,59,249,22,177,7,23,199,1,248,22,183, -3,23,201,1,250,2,60,23,196,4,196,248,22,183,3,198,32,62,88,149,8, -38,42,55,11,2,33,39,223,3,33,69,32,63,88,149,8,38,42,54,11,2, -33,39,223,3,33,66,32,64,88,149,8,38,42,53,11,2,33,39,223,3,33, -65,28,249,22,130,4,23,197,2,23,195,4,248,22,92,194,28,249,22,138,9, -7,47,249,22,159,7,23,198,2,23,199,2,249,22,82,250,22,177,7,23,199, -2,39,23,200,2,248,2,59,249,22,177,7,23,199,1,248,22,183,3,23,201, -1,250,2,64,23,196,4,196,248,22,183,3,198,28,249,22,130,4,23,197,2, -23,195,4,248,22,92,194,28,249,22,138,9,7,47,249,22,159,7,23,198,2, -23,199,2,249,22,82,250,22,177,7,23,199,2,39,23,200,2,27,249,22,177, -7,23,199,1,248,22,183,3,23,201,1,19,248,22,158,7,23,195,2,250,2, -64,23,196,4,23,197,1,39,2,27,248,22,183,3,23,197,1,28,249,22,130, -4,23,195,2,23,196,4,248,22,92,195,28,249,22,138,9,7,47,249,22,159, -7,23,199,2,23,197,2,249,22,82,250,22,177,7,23,200,2,39,23,198,2, -248,2,59,249,22,177,7,23,200,1,248,22,183,3,23,199,1,250,2,63,23, -197,4,197,248,22,183,3,196,32,67,88,149,8,38,42,53,11,2,33,39,223, -3,33,68,28,249,22,130,4,23,197,2,23,195,4,248,22,92,194,28,249,22, -138,9,7,47,249,22,159,7,23,198,2,23,199,2,249,22,82,250,22,177,7, -23,199,2,39,23,200,2,248,2,59,249,22,177,7,23,199,1,248,22,183,3, -23,201,1,250,2,67,23,196,4,196,248,22,183,3,198,28,249,22,130,4,23, -197,2,23,195,4,248,22,92,194,28,249,22,138,9,7,47,249,22,159,7,23, -198,2,23,199,2,249,22,82,250,22,177,7,23,199,2,39,23,200,2,27,249, -22,177,7,23,199,1,248,22,183,3,23,201,1,19,248,22,158,7,23,195,2, -250,2,63,23,196,4,23,197,1,39,2,27,248,22,183,3,23,197,1,28,249, -22,130,4,23,195,2,23,196,4,248,22,92,195,28,249,22,138,9,7,47,249, -22,159,7,23,199,2,23,197,2,249,22,82,250,22,177,7,23,200,2,39,23, -198,2,27,249,22,177,7,23,200,1,248,22,183,3,23,199,1,19,248,22,158, -7,23,195,2,250,2,67,23,196,4,23,197,1,39,2,27,248,22,183,3,23, -195,1,28,249,22,130,4,23,195,2,23,197,4,248,22,92,196,28,249,22,138, -9,7,47,249,22,159,7,23,200,2,23,197,2,249,22,82,250,22,177,7,23, -201,2,39,23,198,2,248,2,59,249,22,177,7,23,201,1,248,22,183,3,23, -199,1,250,2,62,23,198,4,198,248,22,183,3,196,19,248,22,158,7,23,195, -2,28,249,22,130,4,39,23,195,4,248,22,92,194,28,249,22,138,9,7,47, -249,22,159,7,23,198,2,39,249,22,82,250,22,177,7,23,199,2,39,39,27, -249,22,177,7,23,199,1,40,19,248,22,158,7,23,195,2,250,2,60,23,196, -4,23,197,1,39,2,28,249,22,130,4,40,23,195,4,248,22,92,194,28,249, -22,138,9,7,47,249,22,159,7,23,198,2,40,249,22,82,250,22,177,7,23, -199,2,39,40,248,2,59,249,22,177,7,23,199,1,41,250,2,62,23,196,4, -196,41,2,28,249,22,130,4,23,197,2,23,195,4,248,22,92,194,28,249,22, -138,9,7,47,249,22,159,7,23,198,2,23,199,2,249,22,82,250,22,177,7, -23,199,2,39,23,200,2,248,2,59,249,22,177,7,23,199,1,248,22,183,3, -23,201,1,250,2,58,23,196,4,196,248,22,183,3,198,28,249,22,130,4,23, -197,2,23,195,4,248,22,92,194,28,249,22,138,9,7,47,249,22,159,7,23, -198,2,23,199,2,249,22,82,250,22,177,7,23,199,2,39,23,200,2,27,249, -22,177,7,23,199,1,248,22,183,3,23,201,1,19,248,22,158,7,23,195,2, -250,2,58,23,196,4,23,197,1,39,2,27,248,22,183,3,23,197,1,28,249, -22,130,4,23,195,2,23,196,4,248,22,92,195,28,249,22,138,9,7,47,249, -22,159,7,23,199,2,23,197,2,249,22,82,250,22,177,7,23,200,2,39,23, -198,2,248,2,59,249,22,177,7,23,200,1,248,22,183,3,23,199,1,250,2, -57,23,197,4,197,248,22,183,3,196,32,73,88,148,39,40,58,11,2,34,222, -33,74,28,248,22,90,248,22,84,23,195,2,249,22,7,9,248,22,163,20,23, -196,1,90,144,41,11,89,146,41,39,11,27,248,22,164,20,23,197,2,28,248, -22,90,248,22,84,23,195,2,249,22,7,9,248,22,163,20,195,90,144,41,11, -89,146,41,39,11,27,248,22,164,20,196,28,248,22,90,248,22,84,23,195,2, -249,22,7,9,248,22,163,20,195,90,144,41,11,89,146,41,39,11,248,2,73, -248,22,164,20,196,249,22,7,249,22,82,248,22,163,20,199,196,195,249,22,7, -249,22,82,248,22,163,20,199,196,195,249,22,7,249,22,82,248,22,163,20,23, -200,1,23,197,1,23,196,1,27,19,248,22,158,7,23,196,2,250,2,57,23, -196,4,23,198,1,39,2,28,23,195,1,192,28,248,22,90,248,22,84,23,195, -2,249,22,7,9,248,22,163,20,23,196,1,27,248,22,164,20,23,195,2,90, -144,41,11,89,146,41,39,11,28,248,22,90,248,22,84,23,197,2,249,22,7, -9,248,22,163,20,23,198,1,27,248,22,164,20,23,197,2,90,144,41,11,89, -146,41,39,11,28,248,22,90,248,22,84,23,197,2,249,22,7,9,248,22,163, -20,197,90,144,41,11,89,146,41,39,11,248,2,73,248,22,164,20,198,249,22, -7,249,22,82,248,22,163,20,201,196,195,249,22,7,249,22,82,248,22,163,20, -23,203,1,196,195,249,22,7,249,22,82,248,22,163,20,23,201,1,23,197,1, -23,196,1,248,22,144,12,252,22,163,10,248,22,165,4,23,200,2,248,22,161, -4,23,200,2,248,22,162,4,23,200,2,248,22,163,4,23,200,2,248,22,164, -4,23,200,1,28,24,194,2,12,20,13,144,80,144,39,61,40,80,143,39,59, -89,146,40,40,10,249,22,132,5,21,94,2,35,6,19,19,112,108,97,110,101, -116,47,114,101,115,111,108,118,101,114,46,114,107,116,1,27,112,108,97,110,101, -116,45,109,111,100,117,108,101,45,110,97,109,101,45,114,101,115,111,108,118,101, -114,12,27,28,23,195,2,28,249,22,171,9,23,197,2,80,143,42,55,86,94, -23,195,1,80,143,40,56,27,248,22,155,5,23,197,2,27,28,248,22,80,23, -195,2,248,22,163,20,23,195,1,23,194,1,28,248,22,175,15,23,194,2,90, -144,42,11,89,146,42,39,11,248,22,132,16,23,197,1,86,95,20,18,144,11, -80,143,45,55,199,20,18,144,11,80,143,45,56,192,192,11,11,28,23,193,2, -192,86,94,23,193,1,27,247,22,179,5,28,23,193,2,192,86,94,23,193,1, -247,22,153,16,90,144,42,11,89,146,42,39,11,248,22,132,16,23,198,2,86, -95,23,195,1,23,193,1,28,249,22,168,16,0,11,35,114,120,34,91,46,93, -115,115,36,34,248,22,180,15,23,197,1,249,80,144,44,8,23,42,23,199,1, -2,29,196,249,80,144,41,57,42,195,10,249,22,14,23,196,1,80,144,41,54, -41,86,96,28,248,22,153,5,23,196,2,12,250,22,182,11,2,24,6,21,21, -114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45,112,97,116,104,63, -23,198,2,28,28,23,196,2,248,22,146,14,23,197,2,10,12,250,22,182,11, -2,24,6,20,20,40,111,114,47,99,32,35,102,32,110,97,109,101,115,112,97, -99,101,63,41,23,199,2,28,24,193,2,248,24,194,1,23,196,2,86,94,23, -193,1,12,27,250,22,160,2,80,144,44,44,41,248,22,129,17,247,22,145,14, -11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249,22,82,247,22,140, -2,247,22,140,2,86,94,250,22,158,2,80,144,46,44,41,248,22,129,17,247, -22,145,14,195,192,86,94,250,22,158,2,248,22,83,23,197,2,23,200,2,70, -100,101,99,108,97,114,101,100,28,23,198,2,27,28,248,22,80,248,22,155,5, -23,200,2,248,22,154,5,248,22,83,248,22,155,5,23,201,1,23,198,1,27, -250,22,160,2,80,144,47,44,41,248,22,129,17,23,204,1,11,28,23,193,2, -27,250,22,160,2,248,22,84,23,198,1,23,198,2,11,28,23,193,2,250,22, -158,2,248,22,164,20,23,200,1,23,198,1,23,196,1,12,12,12,86,94,251, -22,139,12,247,22,143,12,67,101,114,114,111,114,6,69,69,100,101,102,97,117, -108,116,32,109,111,100,117,108,101,32,110,97,109,101,32,114,101,115,111,108,118, -101,114,32,99,97,108,108,101,100,32,119,105,116,104,32,116,104,114,101,101,32, -97,114,103,117,109,101,110,116,115,32,40,100,101,112,114,101,99,97,116,101,100, -41,11,251,24,197,1,23,198,1,23,199,1,23,200,1,10,32,84,88,148,39, -41,50,11,78,102,108,97,116,116,101,110,45,115,117,98,45,112,97,116,104,222, -33,87,32,85,88,148,39,43,57,11,2,34,222,33,86,28,248,22,90,23,197, -2,28,248,22,90,195,192,249,22,82,194,248,22,97,197,28,249,22,173,9,248, -22,83,23,199,2,2,38,28,248,22,90,23,196,2,86,95,23,196,1,23,195, -1,250,22,178,11,2,24,6,37,37,116,111,111,32,109,97,110,121,32,34,46, -46,34,115,32,105,110,32,115,117,98,109,111,100,117,108,101,32,112,97,116,104, -58,32,126,46,115,250,22,93,2,37,28,249,22,173,9,23,201,2,2,39,23, -199,1,28,248,22,175,15,23,200,2,23,199,1,249,22,92,28,248,22,66,23, -202,2,2,5,2,40,23,201,1,23,200,1,251,2,85,196,197,248,22,84,199, -248,22,164,20,200,251,2,85,196,197,249,22,82,248,22,163,20,202,200,248,22, -164,20,200,251,2,85,196,197,9,197,27,250,22,178,7,27,28,23,199,2,28, -247,22,131,12,248,80,144,47,58,42,23,200,2,11,11,28,192,192,6,29,29, -115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110,97,109,101,45, -114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,179,16,0,7,35,114, -120,34,92,110,34,23,203,1,249,22,139,8,6,23,23,10,32,32,102,111,114, -32,109,111,100,117,108,101,32,112,97,116,104,58,32,126,115,10,23,202,2,248, -22,174,13,28,23,196,2,251,22,182,12,23,198,1,247,22,29,248,22,92,23, -201,1,23,199,1,86,94,23,196,1,250,22,145,13,23,197,1,247,22,29,23, -198,1,32,89,88,148,8,36,40,53,11,69,115,115,45,62,114,107,116,222,33, -90,19,248,22,158,7,194,28,249,22,134,4,23,195,4,42,28,249,22,171,9, -7,46,249,22,159,7,197,249,22,186,3,23,199,4,42,28,28,249,22,171,9, -7,115,249,22,159,7,197,249,22,186,3,23,199,4,41,249,22,171,9,7,115, -249,22,159,7,197,249,22,186,3,23,199,4,40,11,249,22,178,7,250,22,177, -7,198,39,249,22,186,3,23,200,4,42,2,43,193,193,193,2,28,249,22,161, -7,194,2,39,2,30,28,249,22,161,7,194,2,38,64,117,112,192,0,8,35, -114,120,34,91,46,93,34,32,93,88,148,8,36,40,50,11,2,34,222,33,94, -28,248,22,90,23,194,2,9,250,22,93,6,4,4,10,32,32,32,248,22,179, -15,248,22,105,23,198,2,248,2,93,248,22,164,20,23,198,1,28,249,22,173, -9,248,22,84,23,200,2,23,197,1,28,249,22,171,9,248,22,163,20,23,200, -1,23,196,1,251,22,178,11,2,24,6,41,41,99,121,99,108,101,32,105,110, -32,108,111,97,100,105,110,103,10,32,32,97,116,32,112,97,116,104,58,32,126, -97,10,32,32,112,97,116,104,115,58,126,97,23,200,1,249,22,1,22,178,7, -248,2,93,248,22,97,23,201,1,12,12,247,23,193,1,250,22,159,4,11,196, -195,20,13,144,80,144,49,53,41,249,22,82,249,22,82,23,198,1,23,202,1, -23,195,1,20,13,144,80,144,49,41,40,252,80,144,54,42,40,249,22,33,11, -80,144,56,41,40,22,129,5,23,201,2,22,131,5,248,28,23,208,2,20,20, -94,88,148,8,36,40,49,11,9,223,15,33,97,23,208,1,86,94,23,208,1, -22,7,28,248,22,66,23,207,2,23,206,1,28,28,248,22,80,23,207,2,249, -22,171,9,248,22,163,20,23,209,2,2,35,11,23,206,1,86,94,23,206,1, -28,248,22,153,5,23,203,2,27,248,22,155,5,23,204,2,28,248,22,66,193, -249,22,92,2,5,194,192,23,202,2,249,247,22,178,5,23,201,1,27,248,22, -70,248,22,179,15,23,202,1,28,23,204,2,28,250,22,160,2,248,22,163,20, -23,202,1,23,202,1,11,249,22,82,11,205,249,22,82,194,205,192,86,96,28, -248,22,163,5,23,196,2,12,28,248,22,157,4,23,198,2,250,22,180,11,11, -6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116,104,23,200,2, -250,22,182,11,2,24,2,36,23,198,2,28,28,23,196,2,248,22,153,5,23, -197,2,10,12,250,22,182,11,2,24,6,31,31,40,111,114,47,99,32,35,102, -32,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45,112,97,116,104, -63,41,23,199,2,28,28,23,197,2,248,22,157,4,23,198,2,10,12,250,22, -182,11,2,24,6,17,17,40,111,114,47,99,32,35,102,32,115,121,110,116,97, -120,63,41,23,200,2,28,28,248,22,80,23,196,2,249,22,171,9,248,22,163, -20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23,196,1,23,193,1, -248,22,154,5,248,22,104,23,197,1,28,28,248,22,80,23,196,2,28,249,22, -171,9,248,22,163,20,23,198,2,2,37,28,248,22,80,248,22,104,23,197,2, -249,22,171,9,248,22,108,23,198,2,2,5,11,11,11,86,97,23,198,1,23, -197,1,23,196,1,23,193,1,248,22,154,5,249,2,84,248,22,121,23,199,2, -248,22,106,23,199,1,28,28,248,22,80,23,196,2,28,249,22,171,9,248,22, -163,20,23,198,2,2,37,28,28,249,22,173,9,248,22,104,23,198,2,2,39, -10,249,22,173,9,248,22,104,23,198,2,2,38,28,23,196,2,27,248,22,155, -5,23,198,2,28,248,22,66,193,10,28,248,22,80,193,248,22,66,248,22,163, -20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23,193,1,27,248,22, -155,5,23,198,1,248,22,154,5,249,2,84,28,248,22,80,23,197,2,248,22, -163,20,23,197,2,23,196,2,27,28,249,22,173,9,248,22,104,23,203,2,2, -38,248,22,164,20,200,248,22,106,200,28,248,22,80,23,198,2,249,22,96,248, -22,164,20,199,194,192,28,28,248,22,80,23,196,2,249,22,171,9,248,22,163, -20,23,198,2,2,41,11,86,94,248,80,144,41,8,29,42,23,194,2,253,24, -199,1,23,201,1,23,202,1,23,203,1,23,204,1,11,80,143,46,59,28,28, -248,22,80,23,196,2,28,249,22,171,9,248,22,163,20,23,198,2,2,37,28, -248,22,80,248,22,104,23,197,2,249,22,171,9,248,22,108,23,198,2,2,41, -11,11,11,86,94,248,80,144,41,8,29,42,23,194,2,253,24,199,1,248,22, -104,23,202,2,23,202,1,23,203,1,23,204,1,248,22,106,23,202,1,80,143, -46,59,86,94,23,193,1,27,88,148,8,36,40,57,8,240,0,0,8,0,1, -19,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110,45,101,114,114,225, -2,5,3,33,88,27,28,248,22,80,23,198,2,28,249,22,171,9,2,37,248, -22,163,20,23,200,2,27,248,22,104,23,199,2,28,28,249,22,173,9,23,195, -2,2,39,10,249,22,173,9,23,195,2,2,38,86,94,23,193,1,28,23,199, -2,27,248,22,155,5,23,201,2,28,248,22,80,193,248,22,163,20,193,192,250, -22,178,11,2,24,6,45,45,110,111,32,98,97,115,101,32,112,97,116,104,32, -102,111,114,32,114,101,108,97,116,105,118,101,32,115,117,98,109,111,100,117,108, -101,32,112,97,116,104,58,32,126,46,115,23,201,2,192,23,197,2,23,197,2, -27,28,248,22,80,23,199,2,28,249,22,171,9,2,37,248,22,163,20,23,201, -2,27,28,28,28,249,22,173,9,248,22,104,23,202,2,2,39,10,249,22,173, -9,248,22,104,23,202,2,2,38,23,200,2,11,27,248,22,155,5,23,202,2, -27,28,249,22,173,9,248,22,104,23,204,2,2,38,248,22,164,20,23,202,1, -248,22,106,23,202,1,28,248,22,80,23,195,2,249,2,84,248,22,163,20,23, -197,2,249,22,96,248,22,164,20,23,199,1,23,197,1,249,2,84,23,196,1, -23,195,1,249,2,84,2,39,28,249,22,173,9,248,22,104,23,204,2,2,38, -248,22,164,20,23,202,1,248,22,106,23,202,1,28,248,22,80,193,248,22,164, -20,193,11,11,11,27,28,248,22,66,23,196,2,27,248,80,144,46,51,42,249, -22,82,23,199,2,248,22,129,17,247,22,145,14,28,23,193,2,192,86,94,23, -193,1,90,144,41,11,89,146,41,39,11,249,80,144,49,57,42,248,22,73,23, -201,2,11,27,28,248,22,90,23,195,2,2,42,249,22,178,7,23,197,2,2, -43,252,80,144,53,8,24,42,23,205,1,28,248,22,90,23,200,2,23,200,1, -86,94,23,200,1,248,22,83,23,200,2,28,248,22,90,23,200,2,86,94,23, -199,1,9,248,22,84,23,200,1,23,198,1,10,28,248,22,155,7,23,196,2, -86,94,23,196,1,27,248,80,144,46,8,30,42,23,202,2,27,248,80,144,47, -51,42,249,22,82,23,200,2,23,197,2,28,23,193,2,192,86,94,23,193,1, -90,144,41,11,89,146,41,39,11,249,80,144,50,57,42,23,201,2,11,28,248, -22,90,23,194,2,86,94,23,193,1,249,22,129,16,23,198,1,248,2,89,23, -197,1,250,22,1,22,129,16,23,199,1,249,22,96,249,22,2,32,0,88,148, -8,36,40,47,11,9,222,33,91,23,200,1,248,22,92,248,2,89,23,201,1, -28,248,22,175,15,23,196,2,86,94,23,196,1,248,80,144,45,8,31,42,248, -22,139,16,28,248,22,136,16,23,198,2,23,197,2,249,22,137,16,23,199,2, -248,80,144,49,8,30,42,23,205,2,28,249,22,171,9,248,22,83,23,198,2, -2,35,27,248,80,144,46,51,42,249,22,82,23,199,2,248,22,129,17,247,22, -145,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11,89,146,41,39,11, -249,80,144,49,57,42,248,22,104,23,201,2,11,27,28,248,22,90,248,22,106, -23,201,2,28,248,22,90,23,195,2,249,22,172,16,2,92,23,197,2,11,10, -27,28,23,194,2,248,2,89,23,197,2,28,248,22,90,23,196,2,2,42,28, -249,22,172,16,2,92,23,198,2,248,2,89,23,197,2,249,22,178,7,23,198, -2,2,43,27,28,23,195,1,86,94,23,197,1,249,22,96,28,248,22,90,248, -22,106,23,205,2,21,93,6,5,5,109,122,108,105,98,249,22,1,22,96,249, -22,2,80,144,56,8,32,42,248,22,106,23,208,2,23,198,1,28,248,22,90, -23,197,2,86,94,23,196,1,248,22,92,23,198,1,86,94,23,197,1,23,196, -1,252,80,144,55,8,24,42,23,207,1,248,22,83,23,199,2,248,22,164,20, -23,199,1,23,199,1,10,28,249,22,171,9,248,22,163,20,23,198,2,2,40, -248,80,144,45,8,31,42,248,22,139,16,249,22,137,16,248,22,141,16,248,22, -104,23,201,2,248,80,144,49,8,30,42,23,205,2,12,86,94,28,28,248,22, -175,15,23,194,2,10,248,22,186,8,23,194,2,12,28,23,201,2,250,22,180, -11,69,114,101,113,117,105,114,101,249,22,139,8,6,17,17,98,97,100,32,109, -111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2,248,22,83,23,199, -2,6,0,0,23,204,2,250,22,182,11,2,24,2,36,23,198,2,27,28,248, -22,186,8,23,195,2,249,22,191,8,23,196,2,39,249,22,139,16,248,22,140, -16,23,197,2,11,27,28,248,22,186,8,23,196,2,249,22,191,8,23,197,2, -40,248,80,144,47,8,25,42,23,195,2,90,144,42,11,89,146,42,39,11,28, -248,22,186,8,23,199,2,250,22,7,2,44,249,22,191,8,23,203,2,41,2, -44,248,22,132,16,23,198,2,86,95,23,195,1,23,193,1,27,28,248,22,186, -8,23,200,2,249,22,191,8,23,201,2,42,249,80,144,52,8,23,42,23,197, -2,5,0,27,28,248,22,186,8,23,201,2,249,22,191,8,23,202,2,43,248, -22,154,5,23,200,2,27,250,22,160,2,80,144,55,44,41,248,22,129,17,247, -22,145,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249,22,82, -247,22,140,2,247,22,140,2,86,94,250,22,158,2,80,144,57,44,41,248,22, -129,17,247,22,145,14,195,192,27,28,23,204,2,248,22,154,5,249,22,82,248, -22,155,5,23,200,2,23,207,2,23,196,2,86,95,28,23,212,2,28,250,22, -160,2,248,22,83,23,198,2,195,11,86,96,23,211,1,23,204,1,23,194,1, -12,27,251,22,33,11,80,144,59,53,41,9,28,248,22,17,80,144,60,54,41, -80,144,59,54,41,247,22,19,27,248,22,129,17,247,22,145,14,86,94,249,22, -3,88,148,8,36,40,57,11,9,226,13,12,2,3,33,95,23,196,2,248,28, -248,22,17,80,144,58,54,41,32,0,88,148,39,40,45,11,9,222,33,96,80, -144,57,8,33,42,20,20,98,88,148,39,39,8,25,8,240,12,64,0,0,9, -233,18,21,14,15,12,11,7,6,4,1,2,33,98,23,195,1,23,194,1,23, -197,1,23,207,1,23,214,1,12,28,28,248,22,186,8,23,204,1,86,94,23, -212,1,11,28,23,212,1,28,248,22,155,7,23,206,2,10,28,248,22,66,23, -206,2,10,28,248,22,80,23,206,2,249,22,171,9,248,22,163,20,23,208,2, -2,35,11,11,249,80,144,56,52,42,28,248,22,155,7,23,208,2,249,22,82, -23,209,1,248,80,144,59,8,30,42,23,215,1,86,94,23,212,1,249,22,82, -23,209,1,248,22,129,17,247,22,145,14,252,22,188,8,23,209,1,23,208,1, -23,206,1,23,204,1,23,203,1,12,192,86,96,20,18,144,11,80,143,39,59, -248,80,144,40,8,28,40,249,22,33,11,80,144,42,61,40,248,22,128,5,80, -144,40,60,41,248,22,178,5,80,144,40,40,42,248,22,144,15,80,144,40,48, -42,20,18,144,11,80,143,39,59,248,80,144,40,8,28,40,249,22,33,11,80, -144,42,61,40,20,18,144,11,80,143,39,59,248,80,144,40,8,28,40,249,22, -33,11,80,144,42,61,40,144,39,20,120,145,2,1,39,16,1,11,16,0,20, -26,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9,11,11,11, -10,41,80,143,39,39,20,120,145,2,1,44,16,29,2,3,2,4,30,2,7, -2,8,11,6,30,2,7,1,23,101,120,116,101,110,100,45,112,97,114,97,109, -101,116,101,114,105,122,97,116,105,111,110,11,4,30,2,9,74,112,97,116,104, -45,115,116,114,105,110,103,63,42,196,15,2,10,30,2,9,73,114,101,114,111, -111,116,45,112,97,116,104,44,196,16,30,2,9,77,112,97,116,104,45,97,100, -100,45,115,117,102,102,105,120,44,196,12,2,11,2,12,2,13,2,14,2,15, -2,16,2,17,2,18,2,19,2,20,2,21,2,22,2,23,2,24,30,2,25, -2,8,11,6,30,2,9,1,19,112,97,116,104,45,114,101,112,108,97,99,101, -45,115,117,102,102,105,120,44,196,14,30,2,9,75,102,105,110,100,45,99,111, -108,45,102,105,108,101,49,196,4,30,2,9,78,110,111,114,109,97,108,45,99, -97,115,101,45,112,97,116,104,42,196,11,2,26,2,27,30,2,25,76,114,101, -112,97,114,97,109,101,116,101,114,105,122,101,11,7,16,0,40,42,39,16,0, -39,16,16,2,17,2,18,2,10,2,14,2,19,2,20,2,13,2,4,2,12, -2,3,2,22,2,15,2,16,2,11,2,21,2,24,55,11,11,11,16,3,2, -26,2,23,2,27,16,3,11,11,11,16,3,2,26,2,23,2,27,42,42,40, -12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0, -39,39,16,24,20,15,16,2,248,22,182,8,71,115,111,45,115,117,102,102,105, -120,80,144,39,39,40,20,15,16,2,88,148,39,41,8,39,8,189,3,2,4, -223,0,33,53,80,144,39,40,40,20,15,16,2,32,0,88,148,8,36,44,55, -11,2,11,222,33,54,80,144,39,47,40,20,15,16,2,20,27,143,32,0,88, -148,8,36,40,45,11,2,12,222,192,32,0,88,148,8,36,40,45,11,2,12, -222,192,80,144,39,48,40,20,15,16,2,247,22,143,2,80,144,39,44,40,20, -15,16,2,8,128,8,80,144,39,49,40,20,15,16,2,249,22,187,8,8,128, -8,11,80,144,39,50,40,20,15,16,2,88,148,8,36,40,53,8,128,32,2, -15,223,0,33,55,80,144,39,51,40,20,15,16,2,88,148,8,36,41,57,8, -128,32,2,16,223,0,33,56,80,144,39,52,40,20,15,16,2,247,22,78,80, -144,39,53,40,20,15,16,2,248,22,18,76,109,111,100,117,108,101,45,108,111, -97,100,105,110,103,80,144,39,54,40,20,15,16,2,11,80,143,39,55,20,15, -16,2,11,80,143,39,56,20,15,16,2,32,0,88,148,39,41,60,11,2,21, -222,33,75,80,144,39,57,40,20,15,16,2,32,0,88,148,8,36,40,52,11, -2,22,222,33,76,80,144,39,58,40,20,15,16,2,11,80,143,39,59,20,15, -16,2,88,149,8,34,40,48,8,240,0,0,80,0,1,21,112,114,101,112,45, -112,108,97,110,101,116,45,114,101,115,111,108,118,101,114,33,40,224,1,0,33, -77,80,144,39,8,29,42,20,15,16,2,88,148,39,40,53,8,240,0,0,3, -0,69,103,101,116,45,100,105,114,223,0,33,78,80,144,39,8,30,42,20,15, -16,2,88,148,39,40,52,8,240,0,0,128,0,74,112,97,116,104,45,115,115, -45,62,114,107,116,223,0,33,79,80,144,39,8,31,42,20,15,16,2,88,148, -8,36,40,48,8,240,0,0,4,0,9,223,0,33,80,80,144,39,8,32,42, -20,15,16,2,88,148,39,40,48,8,240,0,128,0,0,9,223,0,33,81,80, -144,39,8,33,42,20,15,16,2,27,11,20,19,143,39,90,144,40,10,89,146, -40,39,10,20,25,96,2,24,88,148,8,36,41,57,8,32,9,224,2,1,33, -82,88,148,39,42,52,11,9,223,0,33,83,88,148,39,43,8,32,16,4,8, -240,44,240,0,0,8,240,156,227,0,0,42,39,9,224,2,1,33,99,207,80, -144,39,60,40,20,15,16,2,88,148,39,39,48,16,2,8,130,8,8,176,65, -2,26,223,0,33,100,80,144,39,8,26,40,20,15,16,2,20,27,143,88,148, -8,36,39,48,16,2,39,8,144,65,2,27,223,0,33,101,88,148,8,36,39, -48,16,2,39,8,144,65,2,27,223,0,33,102,80,144,39,8,27,40,96,29, -94,2,5,70,35,37,107,101,114,110,101,108,11,29,94,2,5,71,35,37,109, -105,110,45,115,116,120,11,2,9,2,25,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 9739); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,1,0,0,8,0, +15,0,26,0,53,0,59,0,73,0,86,0,112,0,129,0,151,0,159,0,171, +0,186,0,202,0,220,0,241,0,253,0,13,1,36,1,60,1,72,1,103,1, +108,1,113,1,131,1,137,1,142,1,151,1,156,1,162,1,167,1,171,1,186, +1,193,1,198,1,202,1,207,1,214,1,225,1,232,1,240,1,87,2,122,2, +225,2,4,3,98,3,133,3,227,3,6,4,7,11,37,11,88,11,163,11,179, +11,195,11,209,11,225,11,44,12,60,12,76,12,92,12,167,12,74,13,90,13, +165,13,160,14,40,15,115,15,22,16,35,16,188,16,116,17,159,17,241,17,113, +18,174,18,182,18,193,18,227,19,74,20,102,20,115,20,36,21,43,21,203,21, +223,21,67,22,89,22,99,22,113,22,151,22,250,22,254,22,5,23,211,23,104, +32,157,32,181,32,205,32,0,0,253,36,0,0,3,1,5,105,110,115,112,48, +68,35,37,98,111,111,116,72,100,108,108,45,115,117,102,102,105,120,1,25,100, +101,102,97,117,108,116,45,108,111,97,100,47,117,115,101,45,99,111,109,112,105, +108,101,100,67,113,117,111,116,101,29,94,2,5,70,35,37,112,97,114,97,109, +122,11,29,94,2,5,69,35,37,117,116,105,108,115,11,1,24,45,109,111,100, +117,108,101,45,104,97,115,104,45,116,97,98,108,101,45,116,97,98,108,101,78, +114,101,103,105,115,116,101,114,45,122,111,45,112,97,116,104,1,20,100,101,102, +97,117,108,116,45,114,101,97,100,101,114,45,103,117,97,114,100,69,67,65,67, +72,69,45,78,73,45,112,97,116,104,45,99,97,99,104,101,76,112,97,116,104, +45,99,97,99,104,101,45,103,101,116,77,112,97,116,104,45,99,97,99,104,101, +45,115,101,116,33,79,45,108,111,97,100,105,110,103,45,102,105,108,101,110,97, +109,101,1,19,45,108,111,97,100,105,110,103,45,112,114,111,109,112,116,45,116, +97,103,73,45,112,114,101,118,45,114,101,108,116,111,77,45,112,114,101,118,45, +114,101,108,116,111,45,100,105,114,1,21,115,112,108,105,116,45,114,101,108,97, +116,105,118,101,45,115,116,114,105,110,103,1,22,102,111,114,109,97,116,45,115, +111,117,114,99,101,45,108,111,99,97,116,105,111,110,73,111,114,105,103,45,112, +97,114,97,109,122,1,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108, +101,45,110,97,109,101,45,114,101,115,111,108,118,101,114,66,98,111,111,116,66, +115,101,97,108,79,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101, +100,5,4,46,114,107,116,66,115,97,109,101,6,6,6,110,97,116,105,118,101, +5,3,46,122,111,67,105,108,111,111,112,66,108,111,111,112,65,108,105,98,6, +12,12,109,111,100,117,108,101,45,112,97,116,104,63,68,115,117,98,109,111,100, +6,2,2,46,46,6,1,1,46,66,102,105,108,101,68,112,108,97,110,101,116, +6,8,8,109,97,105,110,46,114,107,116,6,4,4,46,114,107,116,69,105,103, +110,111,114,101,100,27,252,22,191,15,28,249,22,169,9,23,201,2,2,27,86, +94,23,199,1,23,200,1,28,248,22,132,16,23,200,2,249,22,191,15,23,202, +1,23,201,1,249,80,144,50,45,42,23,202,1,23,201,1,23,203,1,2,28, +247,22,181,8,249,80,144,50,46,42,23,203,1,80,144,50,39,41,27,250,22, +145,16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80, +195,194,11,249,22,5,20,20,96,88,148,8,36,40,57,8,129,3,9,226,5, +4,3,6,33,42,23,199,1,23,196,1,23,197,1,23,195,1,27,252,22,191, +15,28,249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28,248, +22,132,16,23,200,2,249,22,191,15,23,202,1,23,201,1,249,80,144,50,45, +42,23,202,1,23,201,1,23,203,1,2,28,247,22,181,8,249,80,144,50,46, +42,23,203,1,80,144,50,39,41,27,250,22,145,16,196,11,32,0,88,148,8, +36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5,20,20,96, +88,148,8,36,40,57,8,129,3,9,226,5,4,3,6,33,44,23,199,1,23, +196,1,23,197,1,23,195,1,27,250,22,191,15,28,249,22,169,9,23,199,2, +2,27,86,94,23,197,1,23,198,1,28,248,22,132,16,23,198,2,249,22,191, +15,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23,201, +1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,145,16,196,11,32,0, +88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5, +20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6,33,46,23, +199,1,23,196,1,23,197,1,23,195,1,27,250,22,191,15,28,249,22,169,9, +23,199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,132,16,23,198,2, +249,22,191,15,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199, +1,23,201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,145,16,196, +11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11, +249,22,5,20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6, +33,48,23,199,1,23,196,1,23,197,1,23,195,1,86,95,28,248,80,144,40, +43,42,23,195,2,12,250,22,180,11,2,25,6,12,12,112,97,116,104,45,115, +116,114,105,110,103,63,23,197,2,28,28,23,195,2,28,248,22,64,23,196,2, +10,28,248,22,89,23,196,2,28,249,22,130,4,248,22,93,23,198,2,40,28, +28,248,22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,161,20,23,197, +2,249,22,4,22,64,248,22,162,20,23,198,2,11,11,11,10,12,250,22,180, +11,2,25,6,71,71,40,111,114,47,99,32,35,102,32,115,121,109,98,111,108, +63,32,40,99,111,110,115,47,99,32,40,111,114,47,99,32,35,102,32,115,121, +109,98,111,108,63,41,32,40,110,111,110,45,101,109,112,116,121,45,108,105,115, +116,111,102,32,115,121,109,98,111,108,63,41,41,41,23,197,2,27,28,23,196, +2,247,22,191,4,11,27,28,23,194,2,250,22,158,2,80,143,44,44,248,22, +191,16,247,22,143,14,11,11,27,28,23,194,2,250,22,158,2,248,22,82,23, +198,2,23,198,2,11,11,28,23,193,2,86,96,23,197,1,23,195,1,23,194, +1,20,13,144,80,144,42,41,40,250,80,144,45,42,40,249,22,31,11,80,144, +47,41,40,22,128,5,248,22,102,23,197,2,27,248,22,111,23,195,2,20,13, +144,80,144,43,41,40,250,80,144,46,42,40,249,22,31,11,80,144,48,41,40, +22,177,5,28,248,22,173,15,23,197,2,23,196,1,86,94,23,196,1,247,22, +151,16,249,247,22,175,5,248,22,161,20,23,197,1,23,201,1,86,94,23,193, +1,27,28,248,22,134,16,23,199,2,23,198,2,27,247,22,177,5,28,192,249, +22,135,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22, +130,16,23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28,23, +204,2,27,248,22,178,15,23,198,2,19,248,22,147,8,194,28,28,249,22,132, +4,23,195,4,43,249,22,150,8,2,26,249,22,153,8,197,249,22,184,3,23, +199,4,43,11,249,22,7,23,200,2,248,22,182,15,249,22,154,8,250,22,153, +8,201,39,249,22,184,3,23,203,4,43,5,3,46,115,115,249,22,7,23,200, +2,11,2,249,22,7,23,198,2,11,27,28,249,22,169,9,23,196,2,23,199, +2,23,199,2,249,22,191,15,23,198,2,23,196,2,27,28,23,196,2,28,249, +22,169,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,191,15, +23,199,2,23,198,2,86,94,23,198,1,11,27,28,249,22,169,9,23,200,2, +70,114,101,108,97,116,105,118,101,86,94,23,198,1,2,27,23,198,1,27,247, +22,156,16,27,247,22,157,16,27,250,22,145,16,23,201,2,11,32,0,88,148, +8,36,39,44,11,9,222,11,27,28,23,194,2,249,22,80,23,201,2,23,196, +1,86,94,23,194,1,11,27,28,23,199,2,28,23,194,2,11,27,250,22,145, +16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22, +80,23,202,2,194,11,11,27,28,23,195,2,23,195,2,23,194,2,27,28,23, +196,2,23,196,2,248,22,167,9,23,196,2,27,28,23,205,2,28,23,196,2, +86,94,23,197,1,23,196,2,248,22,167,9,23,198,1,11,27,28,23,195,2, +27,249,22,5,88,148,39,40,51,8,129,3,9,226,24,15,12,11,33,43,23, +203,2,27,28,23,198,2,11,193,28,192,192,28,193,28,23,198,2,28,249,22, +132,4,248,22,82,196,248,22,82,23,201,2,193,11,11,11,11,28,23,193,2, +86,105,23,213,1,23,212,1,23,206,1,23,205,1,23,204,1,23,203,1,23, +201,1,23,200,1,23,197,1,23,196,1,23,195,1,23,194,1,20,13,144,80, +144,60,41,40,250,80,144,8,24,42,40,249,22,31,11,80,144,8,26,41,40, +22,128,5,11,20,13,144,80,144,60,41,40,250,80,144,8,24,42,40,249,22, +31,11,80,144,8,26,41,40,22,177,5,28,248,22,173,15,23,206,2,23,205, +1,86,94,23,205,1,247,22,151,16,249,247,22,161,16,248,22,81,23,196,1, +23,218,1,86,94,23,193,1,27,28,23,195,2,27,249,22,5,88,148,39,40, +51,8,129,3,9,226,25,17,13,12,33,45,23,204,2,27,28,23,200,2,11, +193,28,192,192,28,193,28,199,28,249,22,132,4,248,22,82,196,248,22,82,202, +193,11,11,11,11,28,23,193,2,86,103,23,214,1,23,213,1,23,207,1,23, +206,1,23,205,1,23,202,1,23,201,1,23,197,1,23,196,1,23,195,1,20, +13,144,80,144,61,41,40,250,80,144,8,25,42,40,249,22,31,11,80,144,8, +27,41,40,22,128,5,23,207,1,20,13,144,80,144,61,41,40,250,80,144,8, +25,42,40,249,22,31,11,80,144,8,27,41,40,22,177,5,28,248,22,173,15, +23,207,2,23,206,1,86,94,23,206,1,247,22,151,16,249,247,22,161,16,248, +22,81,23,196,1,23,219,1,86,94,23,193,1,27,28,23,197,2,27,249,22, +5,20,20,94,88,148,39,40,51,8,128,3,9,226,26,17,14,13,33,47,23, +210,1,23,205,2,27,28,23,200,2,11,193,28,192,192,28,193,28,23,200,2, +28,249,22,132,4,248,22,82,196,248,22,82,23,203,2,193,11,11,11,86,94, +23,207,1,11,28,23,193,2,86,101,23,208,1,23,206,1,23,205,1,23,203, +1,23,202,1,23,198,1,23,197,1,23,196,1,86,94,27,248,22,81,23,195, +2,28,23,215,2,250,22,156,2,248,22,82,23,219,1,23,219,1,250,22,90, +23,199,1,11,23,211,2,12,20,13,144,80,144,8,23,41,40,250,80,144,8, +26,42,40,249,22,31,11,80,144,8,28,41,40,22,128,5,11,20,13,144,80, +144,8,23,41,40,250,80,144,8,26,42,40,249,22,31,11,80,144,8,28,41, +40,22,177,5,28,248,22,173,15,23,208,2,23,207,1,86,94,23,207,1,247, +22,151,16,249,247,22,175,5,248,22,161,20,23,196,1,23,220,1,86,94,23, +193,1,27,28,23,197,1,27,249,22,5,20,20,95,88,148,39,40,51,8,128, +3,9,226,27,19,15,14,33,49,23,207,1,23,212,1,23,206,1,27,28,23, +201,2,11,193,28,192,192,28,193,28,200,28,249,22,132,4,248,22,82,196,248, +22,82,203,193,11,11,11,86,96,23,209,1,23,204,1,23,203,1,11,28,23, +193,2,86,95,23,207,1,23,198,1,86,94,27,248,22,81,23,195,2,28,23, +216,2,250,22,156,2,248,22,82,23,220,1,23,220,1,250,22,90,23,199,1, +23,213,2,23,212,2,12,20,13,144,80,144,8,24,41,40,250,80,144,8,27, +42,40,249,22,31,11,80,144,8,29,41,40,22,128,5,23,209,1,20,13,144, +80,144,8,24,41,40,250,80,144,8,27,42,40,249,22,31,11,80,144,8,29, +41,40,22,177,5,28,248,22,173,15,23,209,2,23,208,1,86,94,23,208,1, +247,22,151,16,249,247,22,175,5,248,22,161,20,23,196,1,23,221,1,86,94, +23,193,1,28,28,248,22,78,23,220,2,248,22,161,20,23,220,2,10,27,28, +23,199,2,86,94,23,207,1,23,208,1,86,94,23,208,1,23,207,1,28,28, +248,22,78,23,221,2,248,22,167,9,248,22,185,15,23,195,2,11,12,20,13, +144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22,31,11,80,144,8, +30,41,40,22,128,5,28,23,223,2,28,23,202,1,11,23,196,2,86,94,23, +202,1,11,20,13,144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22, +31,11,80,144,8,30,41,40,22,177,5,28,248,22,173,15,23,210,2,23,209, +1,86,94,23,209,1,247,22,151,16,249,247,22,175,5,23,195,1,23,222,1, +12,28,23,194,2,250,22,156,2,248,22,82,23,198,1,23,196,1,250,22,90, +23,201,1,23,202,1,23,203,1,12,27,249,22,189,8,80,144,42,50,41,249, +22,191,3,248,22,187,3,248,22,173,2,200,8,128,8,27,28,193,248,22,176, +2,194,11,28,192,27,249,22,100,198,195,28,192,248,22,82,193,11,11,27,249, +22,191,3,248,22,187,3,248,22,173,2,23,199,2,8,128,8,27,249,22,189, +8,80,144,43,50,41,23,196,2,250,22,190,8,80,144,44,50,41,23,197,1, +248,22,175,2,249,22,80,249,22,80,23,204,1,23,205,1,27,28,23,200,2, +248,22,176,2,200,11,28,192,192,9,32,54,88,149,8,38,42,54,11,2,30, +39,223,3,33,69,32,55,88,149,8,38,42,53,11,2,30,39,223,3,33,68, +32,56,88,148,8,36,40,53,11,2,31,222,33,67,32,57,88,149,8,38,42, +53,11,2,30,39,223,3,33,58,28,249,22,128,4,23,197,2,23,195,4,248, +22,90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249, +22,80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23, +199,1,248,22,181,3,23,201,1,250,2,57,23,196,4,196,248,22,181,3,198, +32,59,88,149,8,38,42,55,11,2,30,39,223,3,33,66,32,60,88,149,8, +38,42,54,11,2,30,39,223,3,33,63,32,61,88,149,8,38,42,53,11,2, +30,39,223,3,33,62,28,249,22,128,4,23,197,2,23,195,4,248,22,90,194, +28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249,22,80,250, +22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23,199,1,248, +22,181,3,23,201,1,250,2,61,23,196,4,196,248,22,181,3,198,28,249,22, +128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7,47,249,22, +157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2,39,23,200, +2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248,22,156,7, +23,195,2,250,2,61,23,196,4,23,197,1,39,2,27,248,22,181,3,23,197, +1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249,22,136,9, +7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175,7,23,200, +2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181,3,23,199, +1,250,2,60,23,197,4,197,248,22,181,3,196,32,64,88,149,8,38,42,53, +11,2,30,39,223,3,33,65,28,249,22,128,4,23,197,2,23,195,4,248,22, +90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249,22, +80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23,199, +1,248,22,181,3,23,201,1,250,2,64,23,196,4,196,248,22,181,3,198,28, +249,22,128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7,47, +249,22,157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2,39, +23,200,2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248,22, +156,7,23,195,2,250,2,60,23,196,4,23,197,1,39,2,27,248,22,181,3, +23,197,1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249,22, +136,9,7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175,7, +23,200,2,39,23,198,2,27,249,22,175,7,23,200,1,248,22,181,3,23,199, +1,19,248,22,156,7,23,195,2,250,2,64,23,196,4,23,197,1,39,2,27, +248,22,181,3,23,195,1,28,249,22,128,4,23,195,2,23,197,4,248,22,90, +196,28,249,22,136,9,7,47,249,22,157,7,23,200,2,23,197,2,249,22,80, +250,22,175,7,23,201,2,39,23,198,2,248,2,56,249,22,175,7,23,201,1, +248,22,181,3,23,199,1,250,2,59,23,198,4,198,248,22,181,3,196,19,248, +22,156,7,23,195,2,28,249,22,128,4,39,23,195,4,248,22,90,194,28,249, +22,136,9,7,47,249,22,157,7,23,198,2,39,249,22,80,250,22,175,7,23, +199,2,39,39,27,249,22,175,7,23,199,1,40,19,248,22,156,7,23,195,2, +250,2,57,23,196,4,23,197,1,39,2,28,249,22,128,4,40,23,195,4,248, +22,90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,40,249,22,80, +250,22,175,7,23,199,2,39,40,248,2,56,249,22,175,7,23,199,1,41,250, +2,59,23,196,4,196,41,2,28,249,22,128,4,23,197,2,23,195,4,248,22, +90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249,22, +80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23,199, +1,248,22,181,3,23,201,1,250,2,55,23,196,4,196,248,22,181,3,198,28, +249,22,128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7,47, +249,22,157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2,39, +23,200,2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248,22, +156,7,23,195,2,250,2,55,23,196,4,23,197,1,39,2,27,248,22,181,3, +23,197,1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249,22, +136,9,7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175,7, +23,200,2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181,3, +23,199,1,250,2,54,23,197,4,197,248,22,181,3,196,32,70,88,148,39,40, +58,11,2,31,222,33,71,28,248,22,88,248,22,82,23,195,2,249,22,7,9, +248,22,161,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,162,20, +23,197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,161,20, +195,90,144,41,11,89,146,41,39,11,27,248,22,162,20,196,28,248,22,88,248, +22,82,23,195,2,249,22,7,9,248,22,161,20,195,90,144,41,11,89,146,41, +39,11,248,2,70,248,22,162,20,196,249,22,7,249,22,80,248,22,161,20,199, +196,195,249,22,7,249,22,80,248,22,161,20,199,196,195,249,22,7,249,22,80, +248,22,161,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23,196, +2,250,2,54,23,196,4,23,198,1,39,2,28,23,195,1,192,28,248,22,88, +248,22,82,23,195,2,249,22,7,9,248,22,161,20,23,196,1,27,248,22,162, +20,23,195,2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23, +197,2,249,22,7,9,248,22,161,20,23,198,1,27,248,22,162,20,23,197,2, +90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23,197,2,249,22, +7,9,248,22,161,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22, +162,20,198,249,22,7,249,22,80,248,22,161,20,201,196,195,249,22,7,249,22, +80,248,22,161,20,23,203,1,196,195,249,22,7,249,22,80,248,22,161,20,23, +201,1,23,197,1,23,196,1,248,22,142,12,252,22,161,10,248,22,163,4,23, +200,2,248,22,159,4,23,200,2,248,22,160,4,23,200,2,248,22,161,4,23, +200,2,248,22,162,4,23,200,1,28,24,194,2,12,20,13,144,80,144,39,41, +40,80,143,39,59,89,146,40,40,10,249,22,130,5,21,94,2,32,6,19,19, +112,108,97,110,101,116,47,114,101,115,111,108,118,101,114,46,114,107,116,1,27, +112,108,97,110,101,116,45,109,111,100,117,108,101,45,110,97,109,101,45,114,101, +115,111,108,118,101,114,12,27,28,23,195,2,28,249,22,169,9,23,197,2,80, +143,42,55,86,94,23,195,1,80,143,40,56,27,248,22,153,5,23,197,2,27, +28,248,22,78,23,195,2,248,22,161,20,23,195,1,23,194,1,28,248,22,173, +15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,1,86, +95,20,18,144,11,80,143,45,55,199,20,18,144,11,80,143,45,56,192,192,11, +11,28,23,193,2,192,86,94,23,193,1,27,247,22,177,5,28,23,193,2,192, +86,94,23,193,1,247,22,151,16,90,144,42,11,89,146,42,39,11,248,22,130, +16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,166,16,0,11,35,114, +120,34,91,46,93,115,115,36,34,248,22,178,15,23,197,1,249,80,144,44,61, +42,23,199,1,2,26,196,249,80,144,41,57,42,195,10,249,22,12,23,196,1, +80,144,41,54,41,86,96,28,248,22,151,5,23,196,2,12,250,22,180,11,2, +22,6,21,21,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45,112, +97,116,104,63,23,198,2,28,28,23,196,2,248,22,144,14,23,197,2,10,12, +250,22,180,11,2,22,6,20,20,40,111,114,47,99,32,35,102,32,110,97,109, +101,115,112,97,99,101,63,41,23,199,2,28,24,193,2,248,24,194,1,23,196, +2,86,94,23,193,1,12,27,250,22,158,2,80,144,44,44,41,248,22,191,16, +247,22,143,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249,22, +80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,46,44,41,248, +22,191,16,247,22,143,14,195,192,86,94,250,22,156,2,248,22,81,23,197,2, +23,200,2,70,100,101,99,108,97,114,101,100,28,23,198,2,27,28,248,22,78, +248,22,153,5,23,200,2,248,22,152,5,248,22,81,248,22,153,5,23,201,1, +23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,191,16,23,204,1,11, +28,23,193,2,27,250,22,158,2,248,22,82,23,198,1,23,198,2,11,28,23, +193,2,250,22,156,2,248,22,162,20,23,200,1,23,198,1,23,196,1,12,12, +12,86,94,251,22,137,12,247,22,141,12,67,101,114,114,111,114,6,69,69,100, +101,102,97,117,108,116,32,109,111,100,117,108,101,32,110,97,109,101,32,114,101, +115,111,108,118,101,114,32,99,97,108,108,101,100,32,119,105,116,104,32,116,104, +114,101,101,32,97,114,103,117,109,101,110,116,115,32,40,100,101,112,114,101,99, +97,116,101,100,41,11,251,24,197,1,23,198,1,23,199,1,23,200,1,10,32, +81,88,148,39,41,50,11,78,102,108,97,116,116,101,110,45,115,117,98,45,112, +97,116,104,222,33,84,32,82,88,148,39,43,57,11,2,31,222,33,83,28,248, +22,88,23,197,2,28,248,22,88,195,192,249,22,80,194,248,22,95,197,28,249, +22,171,9,248,22,81,23,199,2,2,35,28,248,22,88,23,196,2,86,95,23, +196,1,23,195,1,250,22,176,11,2,22,6,37,37,116,111,111,32,109,97,110, +121,32,34,46,46,34,115,32,105,110,32,115,117,98,109,111,100,117,108,101,32, +112,97,116,104,58,32,126,46,115,250,22,91,2,34,28,249,22,171,9,23,201, +2,2,36,23,199,1,28,248,22,173,15,23,200,2,23,199,1,249,22,90,28, +248,22,64,23,202,2,2,5,2,37,23,201,1,23,200,1,251,2,82,196,197, +248,22,82,199,248,22,162,20,200,251,2,82,196,197,249,22,80,248,22,161,20, +202,200,248,22,162,20,200,251,2,82,196,197,9,197,27,250,22,176,7,27,28, +23,199,2,28,247,22,129,12,248,80,144,47,58,42,23,200,2,11,11,28,192, +192,6,29,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110, +97,109,101,45,114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,177,16, +0,7,35,114,120,34,92,110,34,23,203,1,249,22,137,8,6,23,23,10,32, +32,102,111,114,32,109,111,100,117,108,101,32,112,97,116,104,58,32,126,115,10, +23,202,2,248,22,172,13,28,23,196,2,251,22,180,12,23,198,1,247,22,27, +248,22,90,23,201,1,23,199,1,86,94,23,196,1,250,22,143,13,23,197,1, +247,22,27,23,198,1,32,86,88,148,8,36,40,53,11,69,115,115,45,62,114, +107,116,222,33,87,19,248,22,156,7,194,28,249,22,132,4,23,195,4,42,28, +249,22,169,9,7,46,249,22,157,7,197,249,22,184,3,23,199,4,42,28,28, +249,22,169,9,7,115,249,22,157,7,197,249,22,184,3,23,199,4,41,249,22, +169,9,7,115,249,22,157,7,197,249,22,184,3,23,199,4,40,11,249,22,176, +7,250,22,175,7,198,39,249,22,184,3,23,200,4,42,2,40,193,193,193,2, +28,249,22,159,7,194,2,36,2,27,28,249,22,159,7,194,2,35,64,117,112, +192,0,8,35,114,120,34,91,46,93,34,32,90,88,148,8,36,40,50,11,2, +31,222,33,91,28,248,22,88,23,194,2,9,250,22,91,6,4,4,10,32,32, +32,248,22,177,15,248,22,103,23,198,2,248,2,90,248,22,162,20,23,198,1, +28,249,22,171,9,248,22,82,23,200,2,23,197,1,28,249,22,169,9,248,22, +161,20,23,200,1,23,196,1,251,22,176,11,2,22,6,41,41,99,121,99,108, +101,32,105,110,32,108,111,97,100,105,110,103,10,32,32,97,116,32,112,97,116, +104,58,32,126,97,10,32,32,112,97,116,104,115,58,126,97,23,200,1,249,22, +1,22,176,7,248,2,90,248,22,95,23,201,1,12,12,247,23,193,1,250,22, +157,4,11,196,195,20,13,144,80,144,49,53,41,249,22,80,249,22,80,23,198, +1,23,202,1,23,195,1,20,13,144,80,144,49,41,40,252,80,144,54,42,40, +249,22,31,11,80,144,56,41,40,22,191,4,23,201,2,22,129,5,248,28,23, +208,2,20,20,94,88,148,8,36,40,49,11,9,223,15,33,94,23,208,1,86, +94,23,208,1,22,7,28,248,22,64,23,207,2,23,206,1,28,28,248,22,78, +23,207,2,249,22,169,9,248,22,161,20,23,209,2,2,32,11,23,206,1,86, +94,23,206,1,28,248,22,151,5,23,203,2,27,248,22,153,5,23,204,2,28, +248,22,64,193,249,22,90,2,5,194,192,23,202,2,249,247,22,176,5,23,201, +1,27,248,22,68,248,22,177,15,23,202,1,28,23,204,2,28,250,22,158,2, +248,22,161,20,23,202,1,23,202,1,11,249,22,80,11,205,249,22,80,194,205, +192,86,96,28,248,22,161,5,23,196,2,12,28,248,22,155,4,23,198,2,250, +22,178,11,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116, +104,23,200,2,250,22,180,11,2,22,2,33,23,198,2,28,28,23,196,2,248, +22,151,5,23,197,2,10,12,250,22,180,11,2,22,6,31,31,40,111,114,47, +99,32,35,102,32,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, +112,97,116,104,63,41,23,199,2,28,28,23,197,2,248,22,155,4,23,198,2, +10,12,250,22,180,11,2,22,6,17,17,40,111,114,47,99,32,35,102,32,115, +121,110,116,97,120,63,41,23,200,2,28,28,248,22,78,23,196,2,249,22,169, +9,248,22,161,20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23,196, +1,23,193,1,248,22,152,5,248,22,102,23,197,1,28,28,248,22,78,23,196, +2,28,249,22,169,9,248,22,161,20,23,198,2,2,34,28,248,22,78,248,22, +102,23,197,2,249,22,169,9,248,22,106,23,198,2,2,5,11,11,11,86,97, +23,198,1,23,197,1,23,196,1,23,193,1,248,22,152,5,249,2,81,248,22, +119,23,199,2,248,22,104,23,199,1,28,28,248,22,78,23,196,2,28,249,22, +169,9,248,22,161,20,23,198,2,2,34,28,28,249,22,171,9,248,22,102,23, +198,2,2,36,10,249,22,171,9,248,22,102,23,198,2,2,35,28,23,196,2, +27,248,22,153,5,23,198,2,28,248,22,64,193,10,28,248,22,78,193,248,22, +64,248,22,161,20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23,193, +1,27,248,22,153,5,23,198,1,248,22,152,5,249,2,81,28,248,22,78,23, +197,2,248,22,161,20,23,197,2,23,196,2,27,28,249,22,171,9,248,22,102, +23,203,2,2,35,248,22,162,20,200,248,22,104,200,28,248,22,78,23,198,2, +249,22,94,248,22,162,20,199,194,192,28,28,248,22,78,23,196,2,249,22,169, +9,248,22,161,20,23,198,2,2,38,11,86,94,248,80,144,41,8,28,42,23, +194,2,253,24,199,1,23,201,1,23,202,1,23,203,1,23,204,1,11,80,143, +46,59,28,28,248,22,78,23,196,2,28,249,22,169,9,248,22,161,20,23,198, +2,2,34,28,248,22,78,248,22,102,23,197,2,249,22,169,9,248,22,106,23, +198,2,2,38,11,11,11,86,94,248,80,144,41,8,28,42,23,194,2,253,24, +199,1,248,22,102,23,202,2,23,202,1,23,203,1,23,204,1,248,22,104,23, +202,1,80,143,46,59,86,94,23,193,1,27,88,148,8,36,40,57,8,240,0, +0,8,0,1,19,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110,45, +101,114,114,225,2,5,3,33,85,27,28,248,22,78,23,198,2,28,249,22,169, +9,2,34,248,22,161,20,23,200,2,27,248,22,102,23,199,2,28,28,249,22, +171,9,23,195,2,2,36,10,249,22,171,9,23,195,2,2,35,86,94,23,193, +1,28,23,199,2,27,248,22,153,5,23,201,2,28,248,22,78,193,248,22,161, +20,193,192,250,22,176,11,2,22,6,45,45,110,111,32,98,97,115,101,32,112, +97,116,104,32,102,111,114,32,114,101,108,97,116,105,118,101,32,115,117,98,109, +111,100,117,108,101,32,112,97,116,104,58,32,126,46,115,23,201,2,192,23,197, +2,23,197,2,27,28,248,22,78,23,199,2,28,249,22,169,9,2,34,248,22, +161,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23,202,2,2,36, +10,249,22,171,9,248,22,102,23,202,2,2,35,23,200,2,11,27,248,22,153, +5,23,202,2,27,28,249,22,171,9,248,22,102,23,204,2,2,35,248,22,162, +20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2,249,2,81,248, +22,161,20,23,197,2,249,22,94,248,22,162,20,23,199,1,23,197,1,249,2, +81,23,196,1,23,195,1,249,2,81,2,36,28,249,22,171,9,248,22,102,23, +204,2,2,35,248,22,162,20,23,202,1,248,22,104,23,202,1,28,248,22,78, +193,248,22,162,20,193,11,11,11,27,28,248,22,64,23,196,2,27,248,80,144, +46,51,42,249,22,80,23,199,2,248,22,191,16,247,22,143,14,28,23,193,2, +192,86,94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,49,57,42, +248,22,71,23,201,2,11,27,28,248,22,88,23,195,2,2,39,249,22,176,7, +23,197,2,2,40,252,80,144,53,8,23,42,23,205,1,28,248,22,88,23,200, +2,23,200,1,86,94,23,200,1,248,22,81,23,200,2,28,248,22,88,23,200, +2,86,94,23,199,1,9,248,22,82,23,200,1,23,198,1,10,28,248,22,153, +7,23,196,2,86,94,23,196,1,27,248,80,144,46,8,29,42,23,202,2,27, +248,80,144,47,51,42,249,22,80,23,200,2,23,197,2,28,23,193,2,192,86, +94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,50,57,42,23,201, +2,11,28,248,22,88,23,194,2,86,94,23,193,1,249,22,191,15,23,198,1, +248,2,86,23,197,1,250,22,1,22,191,15,23,199,1,249,22,94,249,22,2, +32,0,88,148,8,36,40,47,11,9,222,33,88,23,200,1,248,22,90,248,2, +86,23,201,1,28,248,22,173,15,23,196,2,86,94,23,196,1,248,80,144,45, +8,30,42,248,22,137,16,28,248,22,134,16,23,198,2,23,197,2,249,22,135, +16,23,199,2,248,80,144,49,8,29,42,23,205,2,28,249,22,169,9,248,22, +81,23,198,2,2,32,27,248,80,144,46,51,42,249,22,80,23,199,2,248,22, +191,16,247,22,143,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11,89, +146,41,39,11,249,80,144,49,57,42,248,22,102,23,201,2,11,27,28,248,22, +88,248,22,104,23,201,2,28,248,22,88,23,195,2,249,22,170,16,2,89,23, +197,2,11,10,27,28,23,194,2,248,2,86,23,197,2,28,248,22,88,23,196, +2,2,39,28,249,22,170,16,2,89,23,198,2,248,2,86,23,197,2,249,22, +176,7,23,198,2,2,40,27,28,23,195,1,86,94,23,197,1,249,22,94,28, +248,22,88,248,22,104,23,205,2,21,93,6,5,5,109,122,108,105,98,249,22, +1,22,94,249,22,2,80,144,56,8,31,42,248,22,104,23,208,2,23,198,1, +28,248,22,88,23,197,2,86,94,23,196,1,248,22,90,23,198,1,86,94,23, +197,1,23,196,1,252,80,144,55,8,23,42,23,207,1,248,22,81,23,199,2, +248,22,162,20,23,199,1,23,199,1,10,28,249,22,169,9,248,22,161,20,23, +198,2,2,37,248,80,144,45,8,30,42,248,22,137,16,249,22,135,16,248,22, +139,16,248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86,94, +28,28,248,22,173,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23,201, +2,250,22,178,11,69,114,101,113,117,105,114,101,249,22,137,8,6,17,17,98, +97,100,32,109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2,248, +22,81,23,199,2,6,0,0,23,204,2,250,22,180,11,2,22,2,33,23,198, +2,27,28,248,22,184,8,23,195,2,249,22,189,8,23,196,2,39,249,22,137, +16,248,22,138,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22,189, +8,23,197,2,40,248,80,144,47,8,24,42,23,195,2,90,144,42,11,89,146, +42,39,11,28,248,22,184,8,23,199,2,250,22,7,2,41,249,22,189,8,23, +203,2,41,2,41,248,22,130,16,23,198,2,86,95,23,195,1,23,193,1,27, +28,248,22,184,8,23,200,2,249,22,189,8,23,201,2,42,249,80,144,52,61, +42,23,197,2,5,0,27,28,248,22,184,8,23,201,2,249,22,189,8,23,202, +2,43,248,22,152,5,23,200,2,27,250,22,158,2,80,144,55,44,41,248,22, +191,16,247,22,143,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27, +249,22,80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,57,44, +41,248,22,191,16,247,22,143,14,195,192,27,28,23,204,2,248,22,152,5,249, +22,80,248,22,153,5,23,200,2,23,207,2,23,196,2,86,95,28,23,212,2, +28,250,22,158,2,248,22,81,23,198,2,195,11,86,96,23,211,1,23,204,1, +23,194,1,12,27,251,22,31,11,80,144,59,53,41,9,28,248,22,15,80,144, +60,54,41,80,144,59,54,41,247,22,17,27,248,22,191,16,247,22,143,14,86, +94,249,22,3,88,148,8,36,40,57,11,9,226,13,12,2,3,33,92,23,196, +2,248,28,248,22,15,80,144,58,54,41,32,0,88,148,39,40,45,11,9,222, +33,93,80,144,57,8,32,42,20,20,98,88,148,39,39,8,25,8,240,12,64, +0,0,9,233,18,21,14,15,12,11,7,6,4,1,2,33,95,23,195,1,23, +194,1,23,197,1,23,207,1,23,214,1,12,28,28,248,22,184,8,23,204,1, +86,94,23,212,1,11,28,23,212,1,28,248,22,153,7,23,206,2,10,28,248, +22,64,23,206,2,10,28,248,22,78,23,206,2,249,22,169,9,248,22,161,20, +23,208,2,2,32,11,11,249,80,144,56,52,42,28,248,22,153,7,23,208,2, +249,22,80,23,209,1,248,80,144,59,8,29,42,23,215,1,86,94,23,212,1, +249,22,80,23,209,1,248,22,191,16,247,22,143,14,252,22,186,8,23,209,1, +23,208,1,23,206,1,23,204,1,23,203,1,12,192,86,96,20,18,144,11,80, +143,39,59,248,80,144,40,8,27,40,249,22,31,11,80,144,42,41,40,248,22, +190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,142,15,80, +144,40,48,42,20,18,144,11,80,143,39,59,248,80,144,40,8,27,40,249,22, +31,11,80,144,42,41,40,20,18,144,11,80,143,39,59,248,80,144,40,8,27, +40,249,22,31,11,80,144,42,41,40,144,39,20,121,145,2,1,39,16,1,11, +16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9, +11,11,11,10,41,80,143,39,39,20,121,145,2,1,44,16,28,2,3,2,4, +30,2,6,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110, +45,107,101,121,11,6,30,2,6,1,23,101,120,116,101,110,100,45,112,97,114, +97,109,101,116,101,114,105,122,97,116,105,111,110,11,4,30,2,7,74,112,97, +116,104,45,115,116,114,105,110,103,63,42,196,15,2,8,30,2,7,73,114,101, +114,111,111,116,45,112,97,116,104,44,196,16,30,2,7,77,112,97,116,104,45, +97,100,100,45,115,117,102,102,105,120,44,196,12,2,9,2,10,2,11,2,12, +2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22,30, +2,7,1,19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102, +105,120,44,196,14,30,2,7,75,102,105,110,100,45,99,111,108,45,102,105,108, +101,49,196,4,30,2,7,78,110,111,114,109,97,108,45,99,97,115,101,45,112, +97,116,104,42,196,11,2,23,2,24,30,2,6,76,114,101,112,97,114,97,109, +101,116,101,114,105,122,101,11,7,16,0,40,42,39,16,0,39,16,16,2,15, +2,16,2,8,2,12,2,17,2,18,2,11,2,4,2,10,2,3,2,20,2, +13,2,14,2,9,2,19,2,22,55,11,11,11,16,3,2,23,2,21,2,24, +16,3,11,11,11,16,3,2,23,2,21,2,24,42,42,40,12,11,11,16,0, +16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,24,20, +15,16,2,248,22,180,8,71,115,111,45,115,117,102,102,105,120,80,144,39,39, +40,20,15,16,2,88,148,39,41,8,39,8,189,3,2,4,223,0,33,50,80, +144,39,40,40,20,15,16,2,32,0,88,148,8,36,44,55,11,2,9,222,33, +51,80,144,39,47,40,20,15,16,2,20,28,143,32,0,88,148,8,36,40,45, +11,2,10,222,192,32,0,88,148,8,36,40,45,11,2,10,222,192,80,144,39, +48,40,20,15,16,2,247,22,141,2,80,144,39,44,40,20,15,16,2,8,128, +8,80,144,39,49,40,20,15,16,2,249,22,185,8,8,128,8,11,80,144,39, +50,40,20,15,16,2,88,148,8,36,40,53,8,128,32,2,13,223,0,33,52, +80,144,39,51,40,20,15,16,2,88,148,8,36,41,57,8,128,32,2,14,223, +0,33,53,80,144,39,52,40,20,15,16,2,247,22,76,80,144,39,53,40,20, +15,16,2,248,22,16,76,109,111,100,117,108,101,45,108,111,97,100,105,110,103, +80,144,39,54,40,20,15,16,2,11,80,143,39,55,20,15,16,2,11,80,143, +39,56,20,15,16,2,32,0,88,148,39,41,60,11,2,19,222,33,72,80,144, +39,57,40,20,15,16,2,32,0,88,148,8,36,40,52,11,2,20,222,33,73, +80,144,39,58,40,20,15,16,2,11,80,143,39,59,20,15,16,2,88,149,8, +34,40,48,8,240,4,0,16,0,1,21,112,114,101,112,45,112,108,97,110,101, +116,45,114,101,115,111,108,118,101,114,33,40,224,1,0,33,74,80,144,39,8, +28,42,20,15,16,2,88,148,39,40,53,8,240,0,0,3,0,69,103,101,116, +45,100,105,114,223,0,33,75,80,144,39,8,29,42,20,15,16,2,88,148,39, +40,52,8,240,0,0,64,0,74,112,97,116,104,45,115,115,45,62,114,107,116, +223,0,33,76,80,144,39,8,30,42,20,15,16,2,88,148,8,36,40,48,8, +240,0,0,4,0,9,223,0,33,77,80,144,39,8,31,42,20,15,16,2,88, +148,39,40,48,8,240,0,128,0,0,9,223,0,33,78,80,144,39,8,32,42, +20,15,16,2,27,11,20,19,143,39,90,144,40,10,89,146,40,39,10,20,26, +96,2,22,88,148,8,36,41,57,8,32,9,224,2,1,33,79,88,148,39,42, +52,11,9,223,0,33,80,88,148,39,43,8,32,16,4,8,240,44,240,0,0, +8,240,220,241,0,0,40,39,9,224,2,1,33,96,207,80,144,39,60,40,20, +15,16,2,88,148,39,39,48,16,2,8,134,8,8,176,32,2,23,223,0,33, +97,80,144,39,8,25,40,20,15,16,2,20,28,143,88,148,8,36,39,48,16, +2,43,8,144,32,2,24,223,0,33,98,88,148,8,36,39,48,16,2,43,8, +144,32,2,24,223,0,33,99,80,144,39,8,26,40,96,29,94,2,5,70,35, +37,107,101,114,110,101,108,11,29,94,2,5,71,35,37,109,105,110,45,115,116, +120,11,2,7,2,6,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 9713); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,54,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,1,0,0,8,0, -18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0,134, -0,146,0,229,0,236,0,6,1,0,0,196,1,0,0,3,1,5,105,110,115, +18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0,135, +0,147,0,231,0,238,0,8,1,0,0,198,1,0,0,3,1,5,105,110,115, 112,48,71,35,37,98,117,105,108,116,105,110,67,113,117,111,116,101,29,94,2, 3,70,35,37,107,101,114,110,101,108,11,29,94,2,3,70,35,37,101,120,112, 111,98,115,11,29,94,2,3,68,35,37,98,111,111,116,11,29,94,2,3,76, 35,37,112,108,97,99,101,45,115,116,114,117,99,116,11,29,94,2,3,70,35, 37,112,97,114,97,109,122,11,29,94,2,3,71,35,37,110,101,116,119,111,114, 107,11,29,94,2,3,69,35,37,117,116,105,108,115,11,38,11,93,2,12,36, -12,39,38,13,93,143,16,3,39,2,14,2,2,39,36,14,150,40,143,2,15, -16,4,2,4,39,39,2,1,143,2,15,16,4,2,5,39,39,2,1,143,2, -15,16,4,2,6,39,39,2,1,143,2,15,16,4,2,7,39,39,2,1,143, -2,15,16,4,2,8,39,39,2,1,143,2,15,16,4,2,9,39,39,2,1, -143,2,15,16,4,2,10,39,39,2,1,16,0,38,15,143,2,14,2,11,18, -143,16,2,143,10,16,3,9,2,11,2,13,143,11,16,3,9,9,2,13,16, -3,9,9,9,144,39,20,120,145,2,1,39,16,1,11,16,0,20,26,15,56, -9,2,2,2,2,29,11,11,11,11,11,11,11,9,9,11,11,11,33,16,39, -80,143,39,39,20,120,145,2,1,39,16,0,16,0,40,42,39,16,0,39,16, -0,39,11,11,11,16,0,16,0,16,0,39,39,40,12,11,11,16,0,16,0, -16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,0,104,2,4, -2,5,29,94,2,3,71,35,37,102,111,114,101,105,103,110,11,29,94,2,3, -70,35,37,117,110,115,97,102,101,11,29,94,2,3,71,35,37,102,108,102,120, -110,117,109,11,2,6,2,7,2,8,2,9,2,10,29,94,2,3,69,35,37, -112,108,97,99,101,11,29,94,2,3,71,35,37,102,117,116,117,114,101,115,11, -9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 530); +12,0,39,38,13,93,143,16,3,39,2,14,2,2,39,36,14,1,150,40,143, +2,15,16,4,2,4,39,39,2,1,143,2,15,16,4,2,5,39,39,2,1, +143,2,15,16,4,2,6,39,39,2,1,143,2,15,16,4,2,7,39,39,2, +1,143,2,15,16,4,2,8,39,39,2,1,143,2,15,16,4,2,9,39,39, +2,1,143,2,15,16,4,2,10,39,39,2,1,16,0,38,15,143,2,14,2, +11,18,143,16,2,143,10,16,3,9,2,11,2,13,143,11,16,3,9,9,2, +13,16,3,9,9,9,144,39,20,121,145,2,1,39,16,1,11,16,0,20,27, +15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9,11,11,11,33, +16,39,80,143,39,39,20,121,145,2,1,39,16,0,16,0,40,42,39,16,0, +39,16,0,39,11,11,11,16,0,16,0,16,0,39,39,40,12,11,11,16,0, +16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,0,104, +2,4,2,5,29,94,2,3,71,35,37,102,111,114,101,105,103,110,11,29,94, +2,3,70,35,37,117,110,115,97,102,101,11,29,94,2,3,71,35,37,102,108, +102,120,110,117,109,11,2,6,2,7,2,8,2,9,2,10,29,94,2,3,69, +35,37,112,108,97,99,101,11,29,94,2,3,71,35,37,102,117,116,117,114,101, +115,11,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 532); } diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index 41e72ccfaa..4d4f541641 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -999,6 +999,7 @@ scheme_new_module_env(Scheme_Env *env, Scheme_Module *m, menv->module = m; menv->instance_env = env; + menv->reader_env = (env->reader_env ? env->reader_env : env); if (new_exp_module_tree) { /* It would be nice to share the label env with `env`, but we need @@ -1065,6 +1066,7 @@ void scheme_prepare_exp_env(Scheme_Env *env) eenv->template_env = env; eenv->label_env = env->label_env; eenv->instance_env = env->instance_env; + eenv->reader_env = (env->reader_env ? env->reader_env : env); scheme_prepare_env_stx_context(env); mc = scheme_module_context_at_phase(env->stx_context, scheme_env_phase(eenv)); @@ -1113,6 +1115,7 @@ void scheme_prepare_template_env(Scheme_Env *env) eenv->exp_env = env; eenv->label_env = env->label_env; eenv->instance_env = env->instance_env; + eenv->reader_env = (env->reader_env ? env->reader_env : env); if (env->disallow_unbound) eenv->disallow_unbound = env->disallow_unbound; @@ -1149,6 +1152,7 @@ void scheme_prepare_label_env(Scheme_Env *env) lenv->label_env = lenv; lenv->template_env = lenv; lenv->instance_env = env->instance_env; + lenv->reader_env = (env->reader_env ? env->reader_env : env); } } @@ -1276,6 +1280,7 @@ Scheme_Env *scheme_copy_module_env(Scheme_Env *menv, Scheme_Env *ns, Scheme_Obje scheme_prepare_label_env(ns); menv2->label_env = ns->label_env; + menv2->reader_env = (ns->reader_env ? ns->reader_env : ns); return menv2; } diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index a1f0002fe0..8e3a9123c0 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -331,7 +331,6 @@ scheme_init_fun (Scheme_Env *env) 1, 1, 0, -1); scheme_add_global_constant("call-with-escape-continuation", o, env); - scheme_add_global_constant("call/ec", o, env); REGISTER_SO(internal_call_cc_prim); internal_call_cc_prim = scheme_make_prim_w_arity2(internal_call_cc, @@ -351,7 +350,6 @@ scheme_init_fun (Scheme_Env *env) 0, -1); scheme_add_global_constant("call-with-current-continuation", o, env); - scheme_add_global_constant("call/cc", o, env); scheme_add_global_constant("continuation?", scheme_make_folding_prim(continuation_p, diff --git a/racket/src/racket/src/list.c b/racket/src/racket/src/list.c index 1e9bb352d8..ded6ceac34 100644 --- a/racket/src/racket/src/list.c +++ b/racket/src/racket/src/list.c @@ -604,12 +604,12 @@ scheme_init_list (Scheme_Env *env) scheme_add_global_constant("hash-map", scheme_make_noncm_prim(hash_table_map, "hash-map", - 2, 2), + 2, 3), env); scheme_add_global_constant("hash-for-each", scheme_make_noncm_prim(hash_table_for_each, "hash-for-each", - 2, 2), + 2, 3), env); scheme_add_global_constant("hash-iterate-first", @@ -2552,10 +2552,11 @@ static void no_post_key(const char *name, Scheme_Object *key, int chap) static Scheme_Object *do_map_hash_table(int argc, Scheme_Object *argv[], char *name, - int keep) + int keep, + int try_sorted) { int i; - Scheme_Object *f; + Scheme_Object *f, **sorted_keys; Scheme_Object *first, *last = NULL, *v, *p[2], *obj, *chaperone; obj = argv[0]; @@ -2576,7 +2577,38 @@ static Scheme_Object *do_map_hash_table(int argc, else first = scheme_void; - if (SCHEME_BUCKTP(obj)) { + /* In simple cases, sort keys. This is useful for quasiquote + expansion over hash tables, for example. */ + if (try_sorted && !chaperone && (SCHEME_HASHTP(obj) || SCHEME_HASHTRP(obj))) + sorted_keys = scheme_extract_sorted_keys(obj); + else + sorted_keys = NULL; + + if (sorted_keys) { + if (sorted_keys) { + int i, count; + count = (SCHEME_HASHTP(obj) ? ((Scheme_Hash_Table *)obj)->count : ((Scheme_Hash_Tree *)obj)->count); + for (i = 0; i < count; i++) { + if (SCHEME_HASHTP(obj)) + v = scheme_hash_get((Scheme_Hash_Table *)obj, sorted_keys[i]); + else + v = scheme_hash_tree_get((Scheme_Hash_Tree *)obj, sorted_keys[i]); + if (v) { + p[0] = sorted_keys[i]; + p[1] = v; + v = _scheme_apply(f, 2, p); + if (keep) { + v = lcons(v, scheme_null); + if (last) + SCHEME_CDR(last) = v; + else + first = v; + last = v; + } + } + } + } + } else if (SCHEME_BUCKTP(obj)) { Scheme_Bucket_Table *hash; Scheme_Bucket *bucket; @@ -2683,12 +2715,12 @@ static Scheme_Object *do_map_hash_table(int argc, static Scheme_Object *hash_table_map(int argc, Scheme_Object *argv[]) { - return do_map_hash_table(argc, argv, "hash-map", 1); + return do_map_hash_table(argc, argv, "hash-map", 1, (argc > 2) && SCHEME_TRUEP(argv[2])); } static Scheme_Object *hash_table_for_each(int argc, Scheme_Object *argv[]) { - return do_map_hash_table(argc, argv, "hash-for-each", 0); + return do_map_hash_table(argc, argv, "hash-for-each", 0, (argc > 2) && SCHEME_TRUEP(argv[2])); } static Scheme_Object *hash_table_next(const char *name, mzlonglong start, int argc, Scheme_Object *argv[]) diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 60ef95c1f6..1b5050e07d 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -792,7 +792,6 @@ static Scheme_Object *write_compiled_closure(Scheme_Object *obj) case scheme_toplevel_type: case scheme_local_type: case scheme_local_unbox_type: - case scheme_integer_type: case scheme_true_type: case scheme_false_type: case scheme_void_type: @@ -800,7 +799,10 @@ static Scheme_Object *write_compiled_closure(Scheme_Object *obj) ds = code; break; default: - ds = NULL; + if (SCHEME_NUMBERP(code)) + ds = code; + else + ds = NULL; break; } @@ -850,9 +852,9 @@ static Scheme_Object *write_compiled_closure(Scheme_Object *obj) if (!ds) { if (mt->pass) scheme_signal_error("broken closure-data table\n"); - + code = scheme_protect_quote(data->code); - + ds = scheme_alloc_small_object(); ds->type = scheme_delay_syntax_type; SCHEME_PTR_VAL(ds) = code; @@ -1122,7 +1124,7 @@ static Scheme_Object *make_delayed_syntax(Scheme_Object *stx) { Scheme_Object *ds; Scheme_Marshal_Tables *mt; - + mt = scheme_current_thread->current_mt; if (mt->pass < 0) return stx; @@ -1255,6 +1257,7 @@ static Scheme_Object *ht_to_vector(Scheme_Object *ht) /* recurs for values in hash table; we assume that such nesting is shallow */ { intptr_t i, j, c; + Scheme_Object **sorted_keys; Scheme_Object *k, *val, *vec; if (!ht) @@ -1280,11 +1283,14 @@ static Scheme_Object *ht_to_vector(Scheme_Object *ht) vec = scheme_make_vector(2 * c, NULL); j = 0; - + + sorted_keys = scheme_extract_sorted_keys(ht); + if (SCHEME_HASHTRP(ht)) { Scheme_Hash_Tree *t = (Scheme_Hash_Tree *)ht; - for (i = scheme_hash_tree_next(t, -1); i != -1; i = scheme_hash_tree_next(t, i)) { - scheme_hash_tree_index(t, i, &k, &val); + for (i = 0; i < c; i++) { + k = sorted_keys[i]; + val = scheme_hash_tree_get(t, k); if (SCHEME_HASHTRP(val) || SCHEME_HASHTP(val)) val = ht_to_vector(val); else if (!SAME_OBJ(val, scheme_true)) @@ -1294,16 +1300,15 @@ static Scheme_Object *ht_to_vector(Scheme_Object *ht) } } else { Scheme_Hash_Table *t = (Scheme_Hash_Table *)ht; - for (i = t->size; i--; ) { - if (t->vals[i]) { - val = t->vals[i]; - if (SCHEME_HASHTRP(val) || SCHEME_HASHTP(val)) - val = ht_to_vector(val); - else if (!SAME_OBJ(val, scheme_true)) - val = make_delayed_syntax(val); - SCHEME_VEC_ELS(vec)[j++] = t->keys[i]; - SCHEME_VEC_ELS(vec)[j++] = val; - } + for (i = 0; i < c; i++) { + k = sorted_keys[i]; + val = scheme_hash_get(t, k); + if (SCHEME_HASHTRP(val) || SCHEME_HASHTP(val)) + val = ht_to_vector(val); + else if (!SAME_OBJ(val, scheme_true)) + val = make_delayed_syntax(val); + SCHEME_VEC_ELS(vec)[j++] = k; + SCHEME_VEC_ELS(vec)[j++] = val; } } @@ -1316,17 +1321,18 @@ static Scheme_Object *write_module(Scheme_Object *obj) Scheme_Module_Phase_Exports *pt; Scheme_Object *l, *v, *phase; int i, j, k, count, cnt; + Scheme_Object **sorted_keys; l = scheme_null; cnt = 0; if (m->other_requires) { - for (i = 0; i < m->other_requires->size; i++) { - if (m->other_requires->vals[i]) { - cnt++; - l = scheme_make_pair(m->other_requires->keys[i], - scheme_make_pair(m->other_requires->vals[i], - l)); - } + sorted_keys = scheme_extract_sorted_keys((Scheme_Object *)m->other_requires); + cnt = m->other_requires->count; + for (i = 0; i < cnt; i++) { + l = scheme_make_pair(sorted_keys[i], + scheme_make_pair(scheme_hash_get(m->other_requires, + sorted_keys[i]), + l)); } } l = cons(scheme_make_integer(cnt), l); @@ -1341,7 +1347,11 @@ static Scheme_Object *write_module(Scheme_Object *obj) } cnt = 0; - for (k = -3; k < (m->me->other_phases ? m->me->other_phases->size : 0); k++) { + if (m->me->other_phases) + sorted_keys = scheme_extract_sorted_keys((Scheme_Object *)m->me->other_phases); + else + sorted_keys = NULL; + for (k = -3; k < (m->me->other_phases ? m->me->other_phases->count : 0); k++) { switch (k) { case -3: phase = scheme_make_integer(-1); @@ -1356,8 +1366,8 @@ static Scheme_Object *write_module(Scheme_Object *obj) pt = m->me->rt; break; default: - phase = m->me->other_phases->keys[k]; - pt = (Scheme_Module_Phase_Exports *)m->me->other_phases->vals[k]; + phase = sorted_keys[k]; + pt = (Scheme_Module_Phase_Exports *)scheme_hash_get(m->me->other_phases, phase); } if (pt) { diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 6df3c0f974..bf6cc7b660 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -10617,6 +10617,9 @@ void compute_provide_arrays(Scheme_Hash_Table *all_provided, Scheme_Hash_Table * having a consistent provide arrays. */ qsort_provides(exs, exsns, exss, exps, exets, exsnoms, 0, exvcount, 1); + /* Sort syntax, too, for deterministic output */ + qsort_provides(exs, exsns, exss, exps, exets, exsnoms, exvcount, excount-exvcount, 0); + pt->num_provides = excount; pt->num_var_provides = exvcount; pt->provides = exs; @@ -11888,7 +11891,8 @@ void scheme_do_module_context_unmarshal(Scheme_Object *modidx, Scheme_Object *re Scheme_Object *bind_phase, Scheme_Object *pt_phase, Scheme_Object *src_phase, Scheme_Object *prefix, /* a sybmol; not included in `excepts` keys */ Scheme_Hash_Tree *excepts, /* NULL => empty */ - Scheme_Hash_Table *export_registry, Scheme_Object *insp_desc, + Scheme_Hash_Table *export_registry, + Scheme_Object *insp_desc, Scheme_Object *req_insp_desc, Scheme_Object *replace_at) { Scheme_Object *name; @@ -11935,7 +11939,7 @@ void scheme_do_module_context_unmarshal(Scheme_Object *modidx, Scheme_Object *re if (pt) { if (!pt->src_modidx && me->src_modidx) pt->src_modidx = me->src_modidx; - scheme_extend_module_context_with_shared(scheme_make_pair(bind_phase, insp_desc), + scheme_extend_module_context_with_shared(scheme_make_pair(bind_phase, req_insp_desc), req_modidx, pt, prefix, excepts, src_phase, context, diff --git a/racket/src/racket/src/mzmark_print.inc b/racket/src/racket/src/mzmark_print.inc index ff4420170e..fa8abafb46 100644 --- a/racket/src/racket/src/mzmark_print.inc +++ b/racket/src/racket/src/mzmark_print.inc @@ -44,6 +44,7 @@ static int mark_marshal_tables_MARK(void *p, struct NewGC *gc) { gcMARK2(mt->reachable_scopes, gc); gcMARK2(mt->reachable_scope_stack, gc); gcMARK2(mt->pending_reachable_ids, gc); + gcMARK2(mt->conditionally_reachable_scopes, gc); gcMARK2(mt->intern_map, gc); gcMARK2(mt->identity_map, gc); gcMARK2(mt->top_map, gc); @@ -65,6 +66,7 @@ static int mark_marshal_tables_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(mt->reachable_scopes, gc); gcFIXUP2(mt->reachable_scope_stack, gc); gcFIXUP2(mt->pending_reachable_ids, gc); + gcFIXUP2(mt->conditionally_reachable_scopes, gc); gcFIXUP2(mt->intern_map, gc); gcFIXUP2(mt->identity_map, gc); gcFIXUP2(mt->top_map, gc); diff --git a/racket/src/racket/src/mzmark_type.inc b/racket/src/racket/src/mzmark_type.inc index a5006620d3..1e35671a42 100644 --- a/racket/src/racket/src/mzmark_type.inc +++ b/racket/src/racket/src/mzmark_type.inc @@ -2297,6 +2297,7 @@ static int namespace_val_MARK(void *p, struct NewGC *gc) { gcMARK2(e->template_env, gc); gcMARK2(e->label_env, gc); gcMARK2(e->instance_env, gc); + gcMARK2(e->reader_env, gc); gcMARK2(e->shadowed_syntax, gc); @@ -2342,6 +2343,7 @@ static int namespace_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(e->template_env, gc); gcFIXUP2(e->label_env, gc); gcFIXUP2(e->instance_env, gc); + gcFIXUP2(e->reader_env, gc); gcFIXUP2(e->shadowed_syntax, gc); diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 477e05a0d3..bcacc22f6a 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -928,6 +928,7 @@ namespace_val { gcMARK2(e->template_env, gc); gcMARK2(e->label_env, gc); gcMARK2(e->instance_env, gc); + gcMARK2(e->reader_env, gc); gcMARK2(e->shadowed_syntax, gc); @@ -1803,6 +1804,7 @@ mark_marshal_tables { gcMARK2(mt->reachable_scopes, gc); gcMARK2(mt->reachable_scope_stack, gc); gcMARK2(mt->pending_reachable_ids, gc); + gcMARK2(mt->conditionally_reachable_scopes, gc); gcMARK2(mt->intern_map, gc); gcMARK2(mt->identity_map, gc); gcMARK2(mt->top_map, gc); diff --git a/racket/src/racket/src/number.c b/racket/src/racket/src/number.c index f0eb6c7083..88f58afdb4 100644 --- a/racket/src/racket/src/number.c +++ b/racket/src/racket/src/number.c @@ -4175,7 +4175,7 @@ scheme_bitwise_shift(int argc, Scheme_Object *argv[]) v = scheme_make_bignum(i); } - if (scheme_current_thread->constant_folding) + if (scheme_current_thread->constant_folding && (shift > 100)) scheme_signal_error("too big"); return scheme_bignum_shift(v, shift); diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index bf89561d01..5228663ab4 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -182,6 +182,8 @@ static Scheme_Object *writable_struct_subs(Scheme_Object *s, int for_write, Prin #define ssQUICKp(x, isbox) (pp ? x : isbox) #define ssALLp(x, isbox) isbox +#define make_hash_table_symtab() scheme_make_hash_table_eqv() + void scheme_init_print(Scheme_Env *env) { int i; @@ -1438,7 +1440,7 @@ static int compare_keys(const void *a, const void *b) Scheme_Object *av, *bv; /* Atomic things first, because they could be used by - marshaled syntax. This cuts donw on recursive reads + marshaled syntax. Sorting cuts down on recursive reads at load time. */ # define SCHEME_FIRSTP(v) (SCHEME_SYMBOLP(v) \ || SCHEME_PATHP(v) \ @@ -1699,7 +1701,7 @@ void scheme_marshal_push_refs(Scheme_Marshal_Tables *mt) mt->st_ref_stack); mt->st_ref_stack = p; - st_refs = scheme_make_hash_table(SCHEME_hash_ptr); + st_refs = make_hash_table_symtab(); mt->st_refs = st_refs; } @@ -1739,6 +1741,39 @@ Scheme_Object *scheme_make_marshal_shared(Scheme_Object *v) return b; } +static Scheme_Object *intern_modidx(Scheme_Hash_Table *interned, Scheme_Object *modidx) +{ + Scheme_Object *l = scheme_null; + Scheme_Modidx *midx; + + while (SAME_TYPE(SCHEME_TYPE(modidx), scheme_module_index_type)) { + midx = (Scheme_Modidx *)modidx; + modidx = scheme_hash_get(interned, modidx); + if (!modidx) { + modidx = (Scheme_Object *)midx; + if (SCHEME_FALSEP(midx->path)) { + scheme_hash_set(interned, modidx, modidx); + break; + } else { + l = scheme_make_pair(modidx, l); + modidx = midx->base; + } + } else + break; + } + + while (!SCHEME_NULLP(l)) { + midx = (Scheme_Modidx *)SCHEME_CAR(l); + modidx = scheme_make_modidx(midx->path, + modidx, + midx->resolved); + scheme_hash_set(interned, modidx, modidx); + l = SCHEME_CDR(l); + } + + return modidx; +} + static void print_escaped(PrintParams *pp, int notdisplay, Scheme_Object *obj, Scheme_Hash_Table *ht, Scheme_Marshal_Tables *mt, int shared) @@ -2321,8 +2356,8 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, { Scheme_Hash_Table *t; Scheme_Hash_Tree *tr; - Scheme_Object **keys, **vals, *val, *key, *orig; - intptr_t i, size; + Scheme_Object **keys, **vals, *val, *key, *orig, **sorted_keys; + intptr_t i, size, count; int did_one = 0; mzlonglong pos; @@ -2373,22 +2408,39 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, tr = (Scheme_Hash_Tree *)obj; } - if (compact) - print_compact_number(pp, t ? t->count : tr->count); - if (t) { keys = t->keys; vals = t->vals; size = t->size; + count = t->count; } else { keys = NULL; vals = NULL; size = tr->count; + count = size; } + + if (compact) + print_compact_number(pp, count); + + /* For determinism, get sorted keys if possible: */ + if (SAME_OBJ(obj, orig)) { + sorted_keys = scheme_extract_sorted_keys(obj); + if (sorted_keys) + size = count; + } else + sorted_keys = NULL; + pos = -1; for (i = 0; i < size; i++) { - if (!vals || vals[i]) { - if (!vals) { + if (!vals || vals[i] || sorted_keys) { + if (sorted_keys) { + key = sorted_keys[i]; + if (t) + val = scheme_hash_get(t, key); + else + val = scheme_hash_tree_get(tr, key); + } else if (!vals) { pos = scheme_hash_tree_next(tr, pos); scheme_hash_tree_index(tr, pos, &key, &val); if (!SAME_OBJ(obj, orig)) @@ -2400,7 +2452,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, if (!SAME_OBJ(obj, orig)) val = scheme_chaperone_hash_traversal_get(orig, key, &key); } else - val = 0; + val = NULL; } if (val) { @@ -2986,6 +3038,13 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, print_compact(pp, CPT_SCOPE); print_symtab_set(pp, mt, obj); idx = get_symtab_idx(mt, obj); + if (mt->reachable_scopes) { + idx = scheme_hash_get(mt->reachable_scopes, obj); + if (!idx) + scheme_signal_error("internal error: found supposedly unreachable scope"); + } else + idx = scheme_make_integer(0); + print_compact_number(pp, SCHEME_INT_VAL(idx)); print(scheme_scope_marshal_content(obj, mt), notdisplay, 1, ht, mt, pp); } } @@ -3009,6 +3068,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, Scheme_Object *idx; if (compact) { + obj = intern_modidx(mt->intern_map, obj); idx = get_symtab_idx(mt, obj); if (idx) { print_symtab_ref(pp, idx); @@ -3263,7 +3323,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, } else if (!mt->pass) { if (!mt->delay_map) { Scheme_Hash_Table *delay_map; - delay_map = scheme_make_hash_table(SCHEME_hash_ptr); + delay_map = make_hash_table_symtab(); mt->delay_map = delay_map; } scheme_hash_set(mt->delay_map, key, obj); @@ -3352,7 +3412,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, /* "D" means "directory": */ print_this_string(pp, "D", 0, 1); - print_number(pp, count); + print_number(pp, count); /* Write the module directory as a binary search tree. */ (void)write_module_tree(pp, a, subtrees, 0, count, init_offset); @@ -3400,21 +3460,28 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, if (compact) closed = print(v, notdisplay, 1, NULL, mt, pp); else { - Scheme_Hash_Table *st_refs, *symtab, *reachable_scopes; + Scheme_Hash_Table *st_refs, *symtab, *reachable_scopes, *intern_map; intptr_t *shared_offsets; intptr_t st_len, j, shared_offset, start_offset; mt = MALLOC_ONE_RT(Scheme_Marshal_Tables); SET_REQUIRED_TAG(mt->type = scheme_rt_marshal_info); scheme_current_thread->current_mt = mt; + + /* We need to compare a modidx using `eq?`, because shifting + is based on `eq`ness. */ + intern_map = scheme_make_hash_table_equal_modix_eq(); + mt->intern_map = intern_map; /* "Print" the string once to find out which scopes are reachable; dropping unreachable scopes drops potentialy large binding tables. */ mt->pass = -1; reachable_scopes = scheme_make_hash_table(SCHEME_hash_ptr); + mt->conditionally_reachable_scopes = reachable_scopes; + reachable_scopes = scheme_make_hash_table(SCHEME_hash_ptr); mt->reachable_scopes = reachable_scopes; mt->reachable_scope_stack = scheme_null; - symtab = scheme_make_hash_table(SCHEME_hash_ptr); + symtab = make_hash_table_symtab(); mt->symtab = symtab; print_substring(v, notdisplay, 1, NULL, mt, pp, NULL, &slen, 0, NULL); scheme_iterate_reachable_scopes(mt); @@ -3425,9 +3492,10 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, SET_REQUIRED_TAG(mt->type = scheme_rt_marshal_info); scheme_current_thread->current_mt = mt; mt->reachable_scopes = reachable_scopes; + mt->intern_map = intern_map; /* Track which shared values are referenced: */ - st_refs = scheme_make_hash_table(SCHEME_hash_ptr); + st_refs = make_hash_table_symtab(); mt->st_refs = st_refs; mt->st_ref_stack = scheme_null; @@ -3436,7 +3504,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, keys, but we also keep track of which things are actually shared; we'll map the original keys to a compacted set of keys for the later passes. */ - symtab = scheme_make_hash_table(SCHEME_hash_ptr); + symtab = make_hash_table_symtab(); mt->symtab = symtab; mt->pass = 0; scheme_hash_set(symtab, scheme_void, scheme_true); /* indicates registration phase */ @@ -3450,7 +3518,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, are re-computed with the compacted keys. */ shared_offsets = MALLOC_N_ATOMIC(intptr_t, mt->st_refs->count); mt->shared_offsets = shared_offsets; - symtab = scheme_make_hash_table(SCHEME_hash_ptr); + symtab = make_hash_table_symtab(); mt->symtab = symtab; mt->top_map = NULL; mt->pass = 1; @@ -3458,7 +3526,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, 1, &st_len); /* "Print" the string again to get a measurement and symtab size. */ - symtab = scheme_make_hash_table(SCHEME_hash_ptr); + symtab = make_hash_table_symtab(); mt->symtab = symtab; mt->top_map = NULL; mt->pass = 2; @@ -3498,7 +3566,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, /* Make symtab again to ensure the same results for the final print: */ - symtab = scheme_make_hash_table(SCHEME_hash_ptr); + symtab = make_hash_table_symtab(); mt->symtab = symtab; mt->top_map = NULL; mt->pass = 3; diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 9d3323c25f..30409ebd00 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -1,4 +1,4 @@ -/* + /* Racket Copyright (c) 2004-2014 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt @@ -4366,6 +4366,7 @@ typedef struct Scheme_Load_Delay { struct Scheme_Load_Delay *clear_bytes_prev; struct Scheme_Load_Delay *clear_bytes_next; int unsafe_ok; + mzlonglong bytecode_hash; } Scheme_Load_Delay; #define ZO_CHECK(x) if (!(x)) scheme_ill_formed_code(port); @@ -4389,6 +4390,7 @@ typedef struct CPort { Scheme_Object *relto; intptr_t *shared_offsets; Scheme_Load_Delay *delay_info; + mzlonglong bytecode_hash; } CPort; #define CP_GETC(cp) ((int)(cp->start[cp->pos++])) #define CP_TELL(port) (port->pos + port->base) @@ -4436,6 +4438,8 @@ static void make_ut(CPort *port) memset(decoded, 0, port->symtab_size); ut->decoded = decoded; + ut->bytecode_hash = port->bytecode_hash; + rht = scheme_make_hash_table(SCHEME_hash_ptr); port->ut->rns = rht; } @@ -5238,8 +5242,11 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) RANGE_POS_CHECK(l, < port->symtab_size); port->symtab[l] = v; } + + l = read_compact_number(port); v2 = read_compact(port, 0); + v2 = scheme_make_pair(scheme_make_integer(l), v2); SCHEME_BOX_VAL(v) = v2; return v; @@ -5380,6 +5387,25 @@ static intptr_t read_simple_number_from_port(Scheme_Object *port) + (d << 24)); } +static void install_byecode_hash_code(CPort *rp, char *hash_code) +{ + mzlonglong l = 0; + int i; + + for (i = 0; i < 20; i++) { + l ^= ((mzlonglong)(hash_code[i]) << ((i % 8) * 8)); + } + + /* Make sure the hash code leaves lots of room for + run-time generated indices: */ +# define LARGE_SPAN ((mzlonglong)1 << 40) + + if (!l) l = LARGE_SPAN; + if (l > 0) l = -l; + if (l > (-LARGE_SPAN)) l -= LARGE_SPAN; + rp->bytecode_hash = l; +} + char *scheme_submodule_path_to_string(Scheme_Object *p, intptr_t *_len) { Scheme_Object *pr; @@ -5661,6 +5687,8 @@ static Scheme_Object *read_compiled(Scheme_Object *port, rp->magic_sym = params->magic_sym; rp->magic_val = params->magic_val; + install_byecode_hash_code(rp, hash_code); + rp->shared_offsets = so; rp->delay_info = delay_info; @@ -5693,6 +5721,7 @@ static Scheme_Object *read_compiled(Scheme_Object *port, delay_info->shared_offsets = rp->shared_offsets; delay_info->relto = rp->relto; delay_info->unsafe_ok = rp->unsafe_ok; + delay_info->bytecode_hash = rp->bytecode_hash; if (SAME_OBJ(delay_info->path, scheme_true)) perma_cache = 1; @@ -5934,6 +5963,7 @@ Scheme_Object *scheme_load_delayed_code(int _which, Scheme_Load_Delay *_delay_in rp->size = size; rp->ut = delay_info->ut; rp->unsafe_ok = delay_info->unsafe_ok; + rp->bytecode_hash = delay_info->bytecode_hash; if (delay_info->ut) delay_info->ut->rp = rp; @@ -6494,6 +6524,10 @@ static Scheme_Object *do_reader(Scheme_Object *try_modpath, { Scheme_Object *modpath, *name, *a[3], *proc, *v, *no_val; int num_a; + Scheme_Env *env; + Scheme_Cont_Frame_Data cframe; + Scheme_Config *config; + int pop_frame; if (stxsrc) modpath = scheme_syntax_to_datum(modpath_stx, 0, NULL); @@ -6534,38 +6568,59 @@ static Scheme_Object *do_reader(Scheme_Object *try_modpath, num_a = 2; } + if (get_info) + pop_frame = 0; + else { + config = scheme_current_config(); + env = scheme_get_env(config); + + if (env->reader_env) { + config = scheme_extend_config(config, + MZCONFIG_ENV, + (Scheme_Object *)env->reader_env); + scheme_push_continuation_frame(&cframe); + scheme_set_cont_mark(scheme_parameterization_key, (Scheme_Object *)config); + pop_frame = 1; + } else + pop_frame = 0; + } + proc = scheme_dynamic_require(num_a, a); if (get_info) { proc = scheme_force_value(proc); } - if (get_info && SAME_OBJ(proc, no_val)) - return scheme_false; - - a[0] = proc; - if (scheme_check_proc_arity(NULL, stxsrc ? 6 : 5, 0, 1, a)) { - /* provide modpath_stx to reader */ - } else if (!get_info && scheme_check_proc_arity(NULL, stxsrc ? 2 : 1, 0, 1, a)) { - /* don't provide modpath_stx to reader */ - modpath_stx = NULL; + if (get_info && SAME_OBJ(proc, no_val)) { + v = scheme_false; } else { - scheme_wrong_contract("#reader", - (stxsrc ? "(or/c (any/c any/c . -> . any) (procedure-arity-includes/c 6))" - : (get_info - ? "(procedure-arity-includes/c 5)" - : "(or/c (any/c . -> . any) (procedure-arity-includes/c 5))")), - -1, -1, a); - return NULL; + a[0] = proc; + if (scheme_check_proc_arity(NULL, stxsrc ? 6 : 5, 0, 1, a)) { + /* provide modpath_stx to reader */ + } else if (!get_info && scheme_check_proc_arity(NULL, stxsrc ? 2 : 1, 0, 1, a)) { + /* don't provide modpath_stx to reader */ + modpath_stx = NULL; + } else { + scheme_wrong_contract("#reader", + (stxsrc ? "(or/c (any/c any/c . -> . any) (procedure-arity-includes/c 6))" + : (get_info + ? "(procedure-arity-includes/c 5)" + : "(or/c (any/c . -> . any) (procedure-arity-includes/c 5))")), + -1, -1, a); + return NULL; + } + + v = readtable_call(0, 0, proc, params, + port, stxsrc, line, col, pos, + get_info, ht, modpath_stx); + + if (!get_info && scheme_special_comment_value(v)) + v = NULL; } - v = readtable_call(0, 0, proc, params, - port, stxsrc, line, col, pos, - get_info, ht, modpath_stx); + if (pop_frame) + scheme_pop_continuation_frame(&cframe); - if (!get_info && scheme_special_comment_value(v)) - return NULL; - else - return v; + return v; } /* "#reader" has been read */ diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 1427fad91f..2ed38ebc30 100644 --- a/racket/src/racket/src/schminc.h +++ b/racket/src/racket/src/schminc.h @@ -12,9 +12,9 @@ finally, set EXPECTED_PRIM_COUNT to the right value and USE_COMPILED_STARTUP to 1 and `make' again. */ -#define USE_COMPILED_STARTUP 0 +#define USE_COMPILED_STARTUP 1 -#define EXPECTED_PRIM_COUNT 1134 +#define EXPECTED_PRIM_COUNT 1132 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 94c66c80b7..6335f1501c 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1235,7 +1235,8 @@ void scheme_do_module_context_unmarshal(Scheme_Object *modidx, Scheme_Object *re Scheme_Object *bind_phase, Scheme_Object *pt_phase, Scheme_Object *src_phase, Scheme_Object *prefix, Scheme_Hash_Tree *excepts, - Scheme_Hash_Table *export_registry, Scheme_Object *insp, + Scheme_Hash_Table *export_registry, + Scheme_Object *insp, Scheme_Object *req_insp, Scheme_Object *replace_at); int scheme_stx_equal_module_context(Scheme_Object *stx, Scheme_Object *mc_as_stx); @@ -3327,6 +3328,7 @@ typedef struct Scheme_Marshal_Tables { Scheme_Hash_Table *reachable_scopes; /* filled on -1 pass */ Scheme_Object *reachable_scope_stack; /* used on -1 pass */ Scheme_Hash_Table *pending_reachable_ids; /* use on -1 pass */ + Scheme_Hash_Table *conditionally_reachable_scopes; /* filled/used on -1 pass */ Scheme_Hash_Table *intern_map; /* filled on first pass */ Scheme_Hash_Table *identity_map; /* filled on first pass */ Scheme_Hash_Table *top_map; /* used on every pass */ @@ -3352,6 +3354,7 @@ typedef struct Scheme_Unmarshal_Tables { Scheme_Hash_Table *rns; struct CPort *rp; char *decoded; + mzlonglong bytecode_hash; } Scheme_Unmarshal_Tables; Scheme_Object *scheme_unmarshal_wrap_get(Scheme_Unmarshal_Tables *ut, @@ -3407,6 +3410,7 @@ struct Scheme_Env { struct Scheme_Env *template_env; struct Scheme_Env *label_env; struct Scheme_Env *instance_env; /* shortcut to env where module is instantiated */ + struct Scheme_Env *reader_env; /* namespace to use for #reader or #lang */ Scheme_Hash_Table *shadowed_syntax; /* top level only */ @@ -4370,6 +4374,8 @@ void scheme_place_set_memory_use(intptr_t amt); void scheme_place_check_memory_use(); void scheme_clear_place_ifs_stack(); +Scheme_Object **scheme_extract_sorted_keys(Scheme_Object *ht); + #ifdef MZ_USE_PLACES Scheme_Object *scheme_place_make_async_channel(); void scheme_place_async_channel_send(Scheme_Object *ch, Scheme_Object *uo); diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 1e2fb67314..391dba2975 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.7" +#define MZSCHEME_VERSION "6.2.900.8" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 7 +#define MZSCHEME_VERSION_W 8 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/startup.inc b/racket/src/racket/src/startup.inc index 7feeb86c6d..a8da4cf8ae 100644 --- a/racket/src/racket/src/startup.inc +++ b/racket/src/racket/src/startup.inc @@ -527,7 +527,7 @@ "(not(car a)))))" "(define-values(get-linked-collections)" "(lambda(links-path)" -"(call/ec(lambda(esc)" +"(call-with-escape-continuation (lambda(esc)" "(define-values(make-handler)" "(lambda(ts)" "(lambda(exn)" diff --git a/racket/src/racket/src/startup.rktl b/racket/src/racket/src/startup.rktl index 58eada16bc..d830a9998c 100644 --- a/racket/src/racket/src/startup.rktl +++ b/racket/src/racket/src/startup.rktl @@ -629,7 +629,8 @@ (lambda (links-path) ;; Use/save information in `links-cache', relying on filesystem-change events ;; or a copy of the file to detect when the cache is stale. - (call/ec (lambda (esc) + (call-with-escape-continuation + (lambda (esc) (define-values (make-handler) (lambda (ts) (lambda (exn) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 60a03d9cea..0a986c1d3f 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -58,7 +58,7 @@ typedef struct Scheme_Scope { Scheme_Inclhash_Object iso; /* 0x1 => Scheme_Scope_With_Owner */ mzlonglong id; /* low SCHEME_STX_SCOPE_KIND_SHIFT bits indicate kind */ Scheme_Object *bindings; /* NULL, vector for one binding, hash table for multiple bindings, - or (rcons hash-table (rcons pes-info ... NULL)); + or (rcons hash-table (rcons (cons scope-set pes-info) ... NULL)); each hash table maps symbols to (cons scope-set binding) or (mlist (cons scope-set binding) ...) */ } Scheme_Scope; @@ -165,6 +165,10 @@ static Scheme_Object *scope_unmarshal_content(Scheme_Object *c, struct Scheme_Un static Scheme_Object *scopes_to_sorted_list(Scheme_Scope_Set *scopes); static void sort_vector_symbols(Scheme_Object *vec); +static void sort_scope_array(Scheme_Object **a, intptr_t count); +static void sort_symbol_array(Scheme_Object **a, intptr_t count); +static void sort_number_array(Scheme_Object **a, intptr_t count); + XFORM_NONGCING static void extract_module_binding_parts(Scheme_Object *l, Scheme_Object *phase, Scheme_Object **_insp_desc, @@ -203,6 +207,10 @@ XFORM_NONGCING static void clear_binding_cache_stx(Scheme_Stx *stx); #define SCHEME_TL_MULTI_SCOPEP(o) (MZ_OPT_HASH_KEY(&(((Scheme_Hash_Table *)o)->iso)) & 0x2) +/* A hash tabel for a multi scope has meta information mapped from void: */ +#define MULTI_SCOPE_METAP(v) SCHEME_VOIDP(v) +#define MULTI_SCOPE_META_HASHEDP(v) SCHEME_MPAIRP(v) + /* Represent fallback as vectors, either of size 2 (for normal scope sets) or size 4 (for sets of propagation instructions, because adding a fallback layer is an action): */ @@ -774,6 +782,7 @@ Scheme_Object *scheme_scope_printed_form(Scheme_Object *m) if (multi_scope) { name = scheme_eq_hash_get((Scheme_Hash_Table *)multi_scope, scheme_void); if (!name) name = scheme_false; + if (MULTI_SCOPE_META_HASHEDP(name)) name = SCHEME_CAR(name); if (SCHEME_TL_MULTI_SCOPEP(multi_scope)) kind_sym = top_symbol; @@ -866,6 +875,14 @@ Scheme_Object *extract_simple_scope(Scheme_Object *multi_scope, Scheme_Object *p ((Scheme_Scope_With_Owner *)m)->owner_multi_scope = (Scheme_Object *)ht; ((Scheme_Scope_With_Owner *)m)->phase = phase; scheme_hash_set(ht, phase, m); + + if (SCHEME_MPAIRP(scheme_hash_get(ht, scheme_void))) { + /* pair indicates loading from bytecode; + zero out id, so that ordering is based on the owner plus the phase; + this approach helps ensure determinstic ordering independent of + the time at which simple scopes are generated */ + ((Scheme_Scope *)m)->id &= SCHEME_STX_SCOPE_KIND_MASK; + } } return m; @@ -4645,18 +4662,21 @@ static Scheme_Object *unmarshal_key_adjust(Scheme_Object *sym, Scheme_Object *pe static void unmarshal_module_context_additions(Scheme_Stx *stx, Scheme_Object *vec, Scheme_Scope_Set *scopes, Scheme_Object *replace_at) { - Scheme_Object *req_modidx, *modidx, *unmarshal_info, *context, *src_phase, *pt_phase, *bind_phase, *insp; + Scheme_Object *req_modidx, *modidx, *unmarshal_info, *context, *src_phase, *pt_phase, *bind_phase; + Scheme_Object *insp, *req_insp; Scheme_Hash_Table *export_registry; req_modidx = SCHEME_VEC_ELS(vec)[0]; insp = SCHEME_VEC_ELS(vec)[3]; - + req_insp = insp; + if (stx) { modidx = apply_modidx_shifts(stx->shifts, req_modidx, &insp, &export_registry); } else { modidx = req_modidx; export_registry = NULL; insp = scheme_false; + req_insp = scheme_false; } src_phase = SCHEME_VEC_ELS(vec)[1]; @@ -4679,7 +4699,7 @@ static void unmarshal_module_context_additions(Scheme_Stx *stx, Scheme_Object *v bind_phase, pt_phase, src_phase, extract_unmarshal_prefix(unmarshal_info), extract_unmarshal_excepts(unmarshal_info), - export_registry, insp, + export_registry, insp, req_insp, replace_at); } @@ -5177,40 +5197,104 @@ Scheme_Object *scheme_flatten_syntax_list(Scheme_Object *lst, int *islist) /* wraps->datum */ /*========================================================================*/ +static void sort_added_scopes(Scheme_Object *scopes, int added) +{ + Scheme_Object **a, *l; + int i; + + if (!added) + return; + + a = MALLOC_N(Scheme_Object *, added); + for (i = 0, l = scopes; i < added; i++, l = SCHEME_CDR(l)) { + a[i] = SCHEME_CAR(l); + } + + sort_scope_array(a, added); + + for (i = 0, l = scopes; i < added; i++, l = SCHEME_CDR(l)) { + SCHEME_CAR(l) = a[i]; + } +} + static void add_reachable_scopes(Scheme_Scope_Set *scopes, Scheme_Marshal_Tables *mt) { - intptr_t i; + intptr_t i, added = 0; Scheme_Object *key, *val; i = -1; while ((i = scope_set_next(scopes, i)) != -1) { scope_set_index(scopes, i, &key, &val); if (!scheme_eq_hash_get(mt->reachable_scopes, key)) { + scheme_hash_set(mt->conditionally_reachable_scopes, key, NULL); scheme_hash_set(mt->reachable_scopes, key, scheme_true); val = scheme_make_pair(key, mt->reachable_scope_stack); mt->reachable_scope_stack = val; + added++; } } + + sort_added_scopes(mt->reachable_scope_stack, added); +} + +static void add_conditional_as_reachable(Scheme_Scope_Set *scopes, Scheme_Marshal_Tables *mt) +{ + int added = 0; + intptr_t i; + Scheme_Object *key, *val; + + STX_ASSERT(SCHEME_SCOPE_SETP(scopes)); + + i = -1; + while ((i = scope_set_next(scopes, i)) != -1) { + scope_set_index(scopes, i, &key, &val); + if (SCHEME_SCOPE_HAS_OWNER((Scheme_Scope *)key) + && scheme_eq_hash_get(mt->conditionally_reachable_scopes, key) + && !scheme_eq_hash_get(mt->reachable_scopes, key)) { + scheme_hash_set(mt->conditionally_reachable_scopes, key, NULL); + scheme_hash_set(mt->reachable_scopes, key, scheme_true); + val = scheme_make_pair(key, mt->reachable_scope_stack); + mt->reachable_scope_stack = val; + added++; + } + } + + sort_added_scopes(mt->reachable_scope_stack, added); } static void add_reachable_multi_scope(Scheme_Object *ms, Scheme_Marshal_Tables *mt) { Scheme_Hash_Table *ht = (Scheme_Hash_Table *)ms; + Scheme_Scope_Set *binding_scopes = empty_scope_set; Scheme_Object *scope; int j; for (j = ht->size; j--; ) { scope = ht->vals[j]; if (scope) { - if (!SCHEME_VOIDP(ht->keys[j])) { - if (!scheme_eq_hash_get(mt->reachable_scopes, scope)) { - scheme_hash_set(mt->reachable_scopes, scope, scheme_true); - scope = scheme_make_pair(scope, mt->reachable_scope_stack); - mt->reachable_scope_stack = scope; + if (!MULTI_SCOPE_METAP(ht->keys[j])) { + if (!scheme_eq_hash_get(mt->reachable_scopes, scope) + && !scheme_eq_hash_get(mt->conditionally_reachable_scopes, scope)) { + /* This scope is reachable via its multi-scope, but it only + matters if it's reachable through a binding (otherwise it + can be re-generated later). We don't want to keep a scope + that can be re-generated, because pruning it makes + compilation more deterministic relative to other + compilations that involve a shared module. If the scope + itself has any bindings, then we count it as reachable + through a binding (which is an approxmation, because other scopes + in the binding may be unreachable, but it seems good enough for + determinism). */ + scheme_hash_set(mt->conditionally_reachable_scopes, scope, scheme_true); + if (((Scheme_Scope *)scope)->bindings) + binding_scopes = scope_set_set(binding_scopes, scope, scheme_true); } } } } + + if (!SAME_OBJ(binding_scopes, empty_scope_set)) + add_conditional_as_reachable(binding_scopes, mt); } static void add_reachable_multi_scopes(Scheme_Object *multi_scopes, Scheme_Marshal_Tables *mt) @@ -5233,16 +5317,27 @@ static void add_reachable_multi_scopes(Scheme_Object *multi_scopes, Scheme_Marsh } } -static Scheme_Object *any_unreachable_scope(Scheme_Scope_Set *scopes, Scheme_Marshal_Tables *mt) +static Scheme_Object *any_unreachable_scope(Scheme_Scope_Set *scopes, Scheme_Marshal_Tables *mt, + int check_conditionals) { intptr_t i; + int saw_conditional = 0; Scheme_Object *key, *val; i = -1; while ((i = scope_set_next(scopes, i)) != -1) { scope_set_index(scopes, i, &key, &val); - if (!scheme_eq_hash_get(mt->reachable_scopes, key)) - return key; + if (!scheme_eq_hash_get(mt->reachable_scopes, key)) { + if (check_conditionals && scheme_eq_hash_get(mt->conditionally_reachable_scopes, key)) + saw_conditional = 1; + else + return key; + } + } + + if (saw_conditional) { + /* since this binding is reachable, move any conditional to reachable */ + add_conditional_as_reachable(scopes, mt); } return NULL; @@ -5263,7 +5358,7 @@ static void possiblly_reachable_free_id(Scheme_Object *val, /* mpair or stx */ STX_ASSERT(SCHEME_STXP((Scheme_Object *)free_id)); - unreachable_scope = any_unreachable_scope(scopes, mt); + unreachable_scope = any_unreachable_scope(scopes, mt, 1); if (!unreachable_scope) { /* causes the free-id mapping's scopes to be reachable: */ @@ -5283,13 +5378,85 @@ static void possiblly_reachable_free_id(Scheme_Object *val, /* mpair or stx */ } } +static int all_symbols(Scheme_Object **a, int c) +{ + while (c--) { + if (!SCHEME_SYMBOLP(a[c])) + return 0; + } + return 1; +} + +static int all_reals(Scheme_Object **a, int c) +{ + while (c--) { + if (!SCHEME_REALP(a[c])) + return 0; + } + return 1; +} + +Scheme_Object **scheme_extract_sorted_keys(Scheme_Object *tree) +{ + intptr_t j, i, count; + Scheme_Object **a, *key; + + if (SCHEME_HASHTRP(tree)) { + Scheme_Hash_Tree *ht = (Scheme_Hash_Tree *)tree; + + count = ht->count; + if (!count) + return NULL; + + a = MALLOC_N(Scheme_Object *, count); + + j = -1; + i = 0; + while ((j = scheme_hash_tree_next(ht, j)) != -1) { + scheme_hash_tree_index(ht, j, &key, NULL); + a[i++] = key; + } + + STX_ASSERT(i == count); + } else { + Scheme_Hash_Table *t = (Scheme_Hash_Table *)tree; + + count = t->count; + + if (!count) + return NULL; + + a = MALLOC_N(Scheme_Object *, count); + j = 0; + + for (i = t->size; i--; ) { + if (t->vals[i]) { + a[j++] = t->keys[i]; + } + } + + STX_ASSERT(j == count); + } + + if (SCHEME_SYMBOLP(a[0]) && all_symbols(a, count)) + sort_symbol_array(a, count); + else if (SCHEME_SCOPEP(a[0])) + sort_scope_array(a, count); + else if (all_reals(a, count)) + sort_number_array(a, count); + else + return NULL; + + return a; +} + void scheme_iterate_reachable_scopes(Scheme_Marshal_Tables *mt) { Scheme_Scope *scope; - Scheme_Object *l, *val, *key; + Scheme_Object *l, *val, *key, **sorted_keys, *pesl; Scheme_Hash_Tree *ht; - int j; - + intptr_t j, count; + /* For each scope, recur on `free-identifier=?` mappings */ while (!SCHEME_NULLP(mt->reachable_scope_stack)) { scope = (Scheme_Scope *)SCHEME_CAR(mt->reachable_scope_stack); @@ -5298,23 +5465,29 @@ void scheme_iterate_reachable_scopes(Scheme_Marshal_Tables *mt) if (scope->bindings) { val = scope->bindings; if (SCHEME_VECTORP(val)) { + add_conditional_as_reachable(SCHEME_VEC_BINDING_SCOPES(val), mt); l = SCHEME_VEC_BINDING_VAL(val); if (SCHEME_MPAIRP(l)) { /* It's a free-id mapping: */ possiblly_reachable_free_id(l, SCHEME_VEC_BINDING_SCOPES(val), mt); } } else { - if (SCHEME_RPAIRP(val)) + if (SCHEME_RPAIRP(val)) { ht = (Scheme_Hash_Tree *)SCHEME_CAR(val); - else { + pesl = SCHEME_CDR(val); + } else { STX_ASSERT(SCHEME_HASHTRP(val)); ht = (Scheme_Hash_Tree *)val; + pesl = NULL; } - j = -1; - while ((j = scheme_hash_tree_next(ht, j)) != -1) { - scheme_hash_tree_index(ht, j, &key, &val); + sorted_keys = scheme_extract_sorted_keys((Scheme_Object *)ht); + count = ht->count; + for (j = 0; j < count; j++) { + key = sorted_keys[j]; + val = scheme_hash_tree_get(ht, key); l = val; if (SCHEME_PAIRP(l)) { + add_conditional_as_reachable(SCHEME_BINDING_SCOPES(l), mt); val = SCHEME_BINDING_VAL(l); if (SCHEME_MPAIRP(val)) { /* It's a free-id mapping: */ @@ -5323,6 +5496,7 @@ void scheme_iterate_reachable_scopes(Scheme_Marshal_Tables *mt) } else { STX_ASSERT(SCHEME_MPAIRP(l)); for (; !SCHEME_NULLP(l); l = SCHEME_CDR(l)) { + add_conditional_as_reachable(SCHEME_BINDING_SCOPES(SCHEME_CAR(l)), mt); val = SCHEME_BINDING_VAL(SCHEME_CAR(l)); if (SCHEME_MPAIRP(val)) { /* It's a free-id mapping: */ @@ -5331,6 +5505,13 @@ void scheme_iterate_reachable_scopes(Scheme_Marshal_Tables *mt) } } } + while (pesl) { + STX_ASSERT(SCHEME_RPAIRP(pesl)); + val = SCHEME_CAR(pesl); + STX_ASSERT(SCHEME_PAIRP(val)); + add_conditional_as_reachable((Scheme_Scope_Set *)SCHEME_CAR(val), mt); + pesl = SCHEME_CDR(pesl); + } } } @@ -5347,6 +5528,16 @@ void scheme_iterate_reachable_scopes(Scheme_Marshal_Tables *mt) } } } + + /* Adjust mapping so that each scope maps to its relative position: */ + { + int i; + sorted_keys = scheme_extract_sorted_keys((Scheme_Object *)mt->reachable_scopes); + for (j = mt->reachable_scopes->count, i = 0; j--; i++) { + STX_ASSERT(SCHEME_SCOPEP(sorted_keys[j])); + scheme_hash_set(mt->reachable_scopes, sorted_keys[j], scheme_make_integer(i)); + } + } } static Scheme_Object *intern_one(Scheme_Object *v, Scheme_Hash_Table *ht) @@ -5424,16 +5615,74 @@ START_XFORM_SKIP; END_XFORM_SKIP; #endif -typedef int (*compar_t)(const void *, const void *); - -static int compare_scopes(const void *a, const void *b) +static int compare_scopes_from_multi(Scheme_Scope *a, Scheme_Scope *b) { - if (*(void **)a == *(void **)b) - return 0; - else if ((*(Scheme_Scope **)a)->id > (*(Scheme_Scope **)b)->id) + Scheme_Scope_With_Owner *ao, *bo; + + ao = (Scheme_Scope_With_Owner *)a; + bo = (Scheme_Scope_With_Owner *)b; + + if (SAME_OBJ(ao->owner_multi_scope, bo->owner_multi_scope)) { + if (SCHEME_FALSEP(ao->phase)) + return 1; + else if (SCHEME_FALSEP(bo->phase)) + return 1; + else if (scheme_bin_lt(ao->phase, bo->phase)) + return 1; + else + return -1; + } else { + Scheme_Object *na, *nb; + na = scheme_hash_get((Scheme_Hash_Table *)ao->owner_multi_scope, scheme_void); + nb = scheme_hash_get((Scheme_Hash_Table *)bo->owner_multi_scope, scheme_void); + STX_ASSERT(MULTI_SCOPE_META_HASHEDP(na)); + STX_ASSERT(MULTI_SCOPE_META_HASHEDP(nb)); + na = SCHEME_CDR(na); + nb = SCHEME_CDR(nb); + STX_ASSERT(SCHEME_REALP(na)); + STX_ASSERT(SCHEME_REALP(nb)); + if (scheme_bin_lt(na, nb)) + return 1; + else if (scheme_bin_lt(nb, na)) + return -1; + else + return 0; + } +} + +static int compare_scopes(const void *_a, const void *_b) +{ + Scheme_Scope *a = *(Scheme_Scope **)_a; + Scheme_Scope *b = *(Scheme_Scope **)_b; + + STX_ASSERT(SCHEME_SCOPEP(a)); + STX_ASSERT(SCHEME_SCOPEP(b)); + + /* Scopes for multi-scopes that were generated late are + ordered before everything else: */ + if (!(a->id >> SCHEME_STX_SCOPE_KIND_SHIFT)) { + STX_ASSERT(SCHEME_SCOPE_HAS_OWNER(a)); + if (b->id >> SCHEME_STX_SCOPE_KIND_SHIFT) + return 1; + STX_ASSERT(SCHEME_SCOPE_HAS_OWNER(b)); + + return compare_scopes_from_multi(a, b); + } else if (!(b->id >> SCHEME_STX_SCOPE_KIND_SHIFT)) { + STX_ASSERT(SCHEME_SCOPE_HAS_OWNER(b)); return -1; - else + } + + if (a->id > b->id) + return -1; + else if (a->id < b->id) return 1; + else + return 0; +} + +static void sort_scope_array(Scheme_Object **a, intptr_t count) +{ + my_qsort(a, count, sizeof(Scheme_Object *), compare_scopes); } static Scheme_Object *scopes_to_sorted_list(Scheme_Scope_Set *scopes) @@ -5450,8 +5699,8 @@ static Scheme_Object *scopes_to_sorted_list(Scheme_Scope_Set *scopes) a[j++] = key; i = scope_set_next(scopes, i); } - - my_qsort(a, j, sizeof(Scheme_Object *), compare_scopes); + + sort_scope_array(a, j); r = scheme_null; for (i = j; i--; ) { @@ -5463,10 +5712,13 @@ static Scheme_Object *scopes_to_sorted_list(Scheme_Scope_Set *scopes) static int compare_syms(const void *_a, const void *_b) { - Scheme_Object *a = (Scheme_Object *)_a; - Scheme_Object *b = (Scheme_Object *)_b; + Scheme_Object *a = *(Scheme_Object **)_a; + Scheme_Object *b = *(Scheme_Object **)_b; intptr_t l = SCHEME_SYM_LEN(a), i; + STX_ASSERT(SCHEME_SYMBOLP(a)); + STX_ASSERT(SCHEME_SYMBOLP(b)); + if (SCHEME_SYM_LEN(b) < l) l = SCHEME_SYM_LEN(b); @@ -5483,6 +5735,38 @@ static void sort_vector_symbols(Scheme_Object *vec) my_qsort(SCHEME_VEC_ELS(vec), SCHEME_VEC_SIZE(vec), sizeof(Scheme_Object *), compare_syms); } +static void sort_symbol_array(Scheme_Object **a, intptr_t count) +{ + my_qsort(a, count, sizeof(Scheme_Object *), compare_syms); +} + +static int compare_nums(const void *_a, const void *_b) +/* also allow #fs */ +{ + Scheme_Object *a = *(Scheme_Object **)_a; + Scheme_Object *b = *(Scheme_Object **)_b; + + if (SCHEME_FALSEP(a)) + return -1; + else if (SCHEME_FALSEP(b)) + return 1; + + STX_ASSERT(SCHEME_REALP(a)); + STX_ASSERT(SCHEME_REALP(b)); + + if (scheme_bin_lt(a, b)) + return -1; + else if (scheme_bin_lt(b, a)) + return 1; + else + return 0; +} + +static void sort_number_array(Scheme_Object **a, intptr_t count) +{ + my_qsort(a, count, sizeof(Scheme_Object *), compare_nums); +} + static Scheme_Object *drop_export_registries(Scheme_Object *shifts) { Scheme_Object *l, *a, *vec, *p, *first = scheme_null, *last = NULL; @@ -5528,11 +5812,30 @@ static void init_identity_map(Scheme_Marshal_Tables *mt) mt->identity_map = id_map; } +static int compare_phased_scopes(const void *_a, const void *_b) +{ + Scheme_Object *a = *(Scheme_Object **)_a; + Scheme_Object *b = *(Scheme_Object **)_b; + + if (SCHEME_FALSEP(a)) + return -1; + else if (SCHEME_FALSEP(b)) + return 1; + else { + STX_ASSERT(SCHEME_REALP(a)); + STX_ASSERT(SCHEME_REALP(b)); + if (scheme_bin_lt(a, b)) + return -1; + else + return 1; + } +} + static Scheme_Object *multi_scope_to_vector(Scheme_Object *multi_scope, Scheme_Marshal_Tables *mt) { Scheme_Object *vec; Scheme_Hash_Table *scopes = (Scheme_Hash_Table *)multi_scope; - intptr_t i, j; + intptr_t i, j, count; if (!mt->identity_map) init_identity_map(mt); @@ -5541,19 +5844,37 @@ static Scheme_Object *multi_scope_to_vector(Scheme_Object *multi_scope, Scheme_M if (vec) return vec; - vec = scheme_make_vector((2 * scopes->count) - 1, scheme_void); + /* only keep reachable scopes: */ + count = 0; + for (i = scopes->size; i--; ) { + if (scopes->vals[i]) { + if (!MULTI_SCOPE_METAP(scopes->keys[i])) { + if (scheme_hash_get(mt->reachable_scopes, scopes->vals[i])) + count++; + } + } + } + + vec = scheme_make_vector((2 * count) + 1, scheme_void); j = 0; for (i = scopes->size; i--; ) { if (scopes->vals[i]) { - if (!SCHEME_VOIDP(scopes->keys[i])) { - SCHEME_VEC_ELS(vec)[j++] = scopes->keys[i]; /* a phase */ - SCHEME_VEC_ELS(vec)[j++] = scopes->vals[i]; /* a scope */ + if (!MULTI_SCOPE_METAP(scopes->keys[i])) { + if (scheme_hash_get(mt->reachable_scopes, scopes->vals[i])) { + SCHEME_VEC_ELS(vec)[j++] = scopes->keys[i]; /* a phase */ + SCHEME_VEC_ELS(vec)[j++] = scopes->vals[i]; /* a scope */ + } } else { - SCHEME_VEC_ELS(vec)[SCHEME_VEC_SIZE(vec)-1] = scopes->vals[i]; /* debug name */ + /* debug name */ + SCHEME_VEC_ELS(vec)[2 * count] = (MULTI_SCOPE_META_HASHEDP(scopes->vals[i]) + ? SCHEME_CAR(scopes->vals[i]) + : scopes->vals[i]); } } } + my_qsort(SCHEME_VEC_ELS(vec), count, 2 * sizeof(Scheme_Object *), compare_phased_scopes); + vec = scheme_make_marshal_shared(vec); scheme_hash_set(mt->identity_map, multi_scope, vec); @@ -5622,12 +5943,6 @@ static Scheme_Object *wraps_to_datum(Scheme_Stx *stx, Scheme_Marshal_Tables *mt) } ht = mt->intern_map; - if (!ht) { - /* We need to compare a modidx using `eq?`, because shifting - is based on `eq`ness. */ - ht = scheme_make_hash_table_equal_modix_eq(); - mt->intern_map = ht; - } shifts = intern_tails(drop_export_registries(stx->shifts), ht); simples = intern_tails(scopes_to_sorted_list(stx->scopes->simple_scopes), ht); @@ -5670,7 +5985,7 @@ static Scheme_Object *marshal_bindings(Scheme_Object *l, Scheme_Marshal_Tables * scopes = (Scheme_Object *)SCHEME_BINDING_SCOPES(SCHEME_CAR(l)); } - if (!any_unreachable_scope((Scheme_Scope_Set *)scopes, mt)) { + if (!any_unreachable_scope((Scheme_Scope_Set *)scopes, mt, 0)) { if (SCHEME_PAIRP(l)) v = SCHEME_BINDING_VAL(l); else @@ -5703,7 +6018,7 @@ static Scheme_Object *marshal_bindings(Scheme_Object *l, Scheme_Marshal_Tables * Scheme_Object *scheme_scope_marshal_content(Scheme_Object *m, Scheme_Marshal_Tables *mt) { Scheme_Hash_Tree *ht; - Scheme_Object *v, *l, *r, *l2, *tab, *scopes, *key, *val; + Scheme_Object *v, *l, *r, *l2, *tab, *scopes, *val, **sorted_keys; intptr_t i, j; if (!mt->identity_map) @@ -5749,16 +6064,17 @@ Scheme_Object *scheme_scope_marshal_content(Scheme_Object *m, Scheme_Marshal_Tab SCHEME_VEC_ELS(tab)[j++] = r; } } else { - i = -1; - while ((i = scheme_hash_tree_next(ht, i)) != -1) { - scheme_hash_tree_index(ht, i, &key, &val); + intptr_t count = ht->count; + sorted_keys = scheme_extract_sorted_keys((Scheme_Object *)ht); + for (i = 0; i < count; i++) { + val = scheme_hash_tree_get(ht, sorted_keys[i]); r = marshal_bindings(val, mt); if (SCHEME_NULLP(r)) { /* no reachable bindings */ } else { STX_ASSERT(j < (2 * count)); - SCHEME_VEC_ELS(tab)[j++] = key; + SCHEME_VEC_ELS(tab)[j++] = sorted_keys[i]; SCHEME_VEC_ELS(tab)[j++] = r; } } @@ -5775,7 +6091,10 @@ Scheme_Object *scheme_scope_marshal_content(Scheme_Object *m, Scheme_Marshal_Tab for (l = l2; l; l = SCHEME_CDR(l)) { STX_ASSERT(SCHEME_RPAIRP(l)); v = SCHEME_CDR(SCHEME_CAR(l)); - if (PES_BINDINGP(v)) { + if (any_unreachable_scope((Scheme_Scope_Set *)SCHEME_CAR(SCHEME_CAR(l)), mt, 0)) { + /* drop unreachable bindings */ + v = NULL; + } else if (PES_BINDINGP(v)) { l2 = scheme_make_vector(4, NULL); SCHEME_VEC_ELS(l2)[0] = SCHEME_VEC_ELS(v)[0]; SCHEME_VEC_ELS(l2)[1] = SCHEME_VEC_ELS(v)[2]; @@ -6156,8 +6475,16 @@ static Scheme_Hash_Table *vector_to_multi_scope(Scheme_Object *mht, Scheme_Unmar len = SCHEME_VEC_SIZE(mht); if (!(len & 1)) return_NULL; + + STX_ASSERT(ut->bytecode_hash); multi_scope = (Scheme_Hash_Table *)new_multi_scope(SCHEME_VEC_ELS(mht)[len-1]); + scheme_hash_set(multi_scope, + scheme_void, + /* record bytecode hash for making fresh scopes for other phases: */ + scheme_make_mutable_pair(scheme_hash_get(multi_scope, scheme_void), + scheme_make_integer_value_from_long_long(ut->bytecode_hash + >> SCHEME_STX_SCOPE_KIND_SHIFT))); len -= 1; /* A multi-scope can refer back to itself via free-id=? info: */ @@ -6201,6 +6528,7 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, multi_scope = vector_to_multi_scope(SCHEME_CAR(SCHEME_CAR(l)), ut); if (!multi_scope) return_NULL; SCHEME_CAR(SCHEME_CAR(l)) = (Scheme_Object *)multi_scope; + if (!SCHEME_PHASE_SHIFTP(SCHEME_CDR(SCHEME_CAR(l)))) return_NULL; } else { /* rest of list must be converted already, too */ break; @@ -6351,7 +6679,7 @@ Scheme_Object *scope_unmarshal_content(Scheme_Object *box, Scheme_Unmarshal_Tabl Scheme_Object *l = NULL, *l2, *r, *b, *m, *c, *free_id; Scheme_Hash_Tree *ht; Scheme_Scope_Set *scopes; - intptr_t i, len; + intptr_t i, len, relative_id; if (SAME_OBJ(box, root_scope)) return root_scope; @@ -6363,6 +6691,11 @@ Scheme_Object *scope_unmarshal_content(Scheme_Object *box, Scheme_Unmarshal_Tabl if (!SCHEME_BOXP(box)) return_NULL; c = SCHEME_BOX_VAL(box); + if (!SCHEME_PAIRP(c)) return_NULL; + + relative_id = SCHEME_INT_VAL(SCHEME_CAR(c)); + c = SCHEME_CDR(c); + if (SCHEME_INTP(c)) { m = scheme_new_scope(SCHEME_INT_VAL(c)); c = NULL; @@ -6375,6 +6708,19 @@ Scheme_Object *scope_unmarshal_content(Scheme_Object *box, Scheme_Unmarshal_Tabl /* Since we've created the scope before unmarshaling its content, cycles among scopes are ok. */ + /* Reset the scope's id to a hash from the bytecode plus a relative + offset. The only use of a scope's id is for debugging and + ordering, and using the bytecode's hash as part of the number is + intended to make ordering deterministic even across modules, + independent of the order that modules are loaded or delay-loaded. + Hashes are not gauarnteed to be distinct or far enough apart, but + they're likely to be. */ + STX_ASSERT(ut->bytecode_hash); + ((Scheme_Scope *)m)->id = ((SCHEME_STX_SCOPE_KIND_MASK & ((Scheme_Scope*)m)->id) + | ((umzlonglong)((relative_id << SCHEME_STX_SCOPE_KIND_SHIFT) + + ut->bytecode_hash) + & (~(umzlonglong)SCHEME_STX_SCOPE_KIND_MASK))); + if (!c) return m; while (SCHEME_PAIRP(c)) { From fe2e480ef18bcc771b728b61c83daa294a94f425 Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Fri, 7 Aug 2015 18:40:08 -0400 Subject: [PATCH 009/381] syntax/parse doc typo in ~describe --- pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl index bd446e9208..8d6baee336 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl @@ -572,7 +572,7 @@ above). ] } -@specsubform[(@#,def[~describe s] maybe-opaque expr S-pattern) +@specsubform[(@#,def[~describe s] maybe-role maybe-opaque expr S-pattern) #:grammar ([maybe-opaque (code:line) (code:line #:opaque)] From 9f682a3f11499b7c19eca5c1af0fa538d65637fe Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 7 Aug 2015 19:08:21 -0400 Subject: [PATCH 010/381] Add prefab structs to match grammar --- pkgs/racket-doc/scribblings/reference/match-grammar.rkt | 1 + pkgs/racket-doc/scribblings/reference/match-parse.rkt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/pkgs/racket-doc/scribblings/reference/match-grammar.rkt b/pkgs/racket-doc/scribblings/reference/match-grammar.rkt index 568267f7a6..157df1e95b 100644 --- a/pkgs/racket-doc/scribblings/reference/match-grammar.rkt +++ b/pkgs/racket-doc/scribblings/reference/match-grammar.rkt @@ -50,6 +50,7 @@ qp ::= literal @match literal | (qp ooo . qp) @match qps beginning with repeated qp | #(qp ...) @match vector of qps | #&qp @match boxed qp + | #s(prefab-key qp ...) @match prefab struct with qp fields | ,pat @match pat | ,@(LIST lvp ...) @match lvps, spliced | ,@(LIST-REST lvp ... pat) @match lvps plus pat, spliced diff --git a/pkgs/racket-doc/scribblings/reference/match-parse.rkt b/pkgs/racket-doc/scribblings/reference/match-parse.rkt index 81d6c50b93..3f6df400b2 100644 --- a/pkgs/racket-doc/scribblings/reference/match-parse.rkt +++ b/pkgs/racket-doc/scribblings/reference/match-parse.rkt @@ -58,6 +58,10 @@ (list->vector (map fixup-sexp (vector->list s)))] [(box? s) (box (fixup-sexp (unbox s)))] + [(struct? s) + (apply make-prefab-struct + (prefab-struct-key s) + (cdr (map fixup-sexp (vector->list (struct->vector s)))))] [(symbol? s) (case s [(lvp pat qp literal ooo datum struct-id From e9e7e42b6488caf4ecfeb9cd3d5a9e14ea5320ee Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 9 Aug 2015 10:50:50 -0500 Subject: [PATCH 011/381] Fix generics tests for hashing change. --- pkgs/racket-test/tests/generic/base-interfaces.rkt | 4 ++-- pkgs/racket-test/tests/generic/equal+hash.rkt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test/tests/generic/base-interfaces.rkt b/pkgs/racket-test/tests/generic/base-interfaces.rkt index 43c1a3e568..15deb83d9b 100644 --- a/pkgs/racket-test/tests/generic/base-interfaces.rkt +++ b/pkgs/racket-test/tests/generic/base-interfaces.rkt @@ -27,5 +27,5 @@ ;; ok if these don't raise unbound id errors (check-equal? (with-output-to-string (lambda () (write (tuple 5)))) "#0=#0#") (check-equal? (tuple 5) (tuple 5)) - (check-equal? (equal-hash-code (tuple 5)) 53) - (check-equal? (equal-secondary-hash-code (tuple 5)) 44)) + (check-equal? (equal-hash-code (tuple 5)) 54) + (check-equal? (equal-secondary-hash-code (tuple 5)) 45)) diff --git a/pkgs/racket-test/tests/generic/equal+hash.rkt b/pkgs/racket-test/tests/generic/equal+hash.rkt index b6a765cda4..a72707c6e8 100644 --- a/pkgs/racket-test/tests/generic/equal+hash.rkt +++ b/pkgs/racket-test/tests/generic/equal+hash.rkt @@ -16,5 +16,5 @@ (check-false (equal? (kons 1 2) 2)) (check-false (equal? 2 (kons 1 2))) (check-false (equal? (kons 1 2) (kons 3 4))) - (check-equal? (equal-hash-code (kons 1 2)) 60) + (check-equal? (equal-hash-code (kons 1 2)) 61) ) From d66da8ff3b7c7f1d113e32032711cc4c2a1a23e0 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 10 Aug 2015 11:56:33 -0500 Subject: [PATCH 012/381] Fix argument order in guide. Closes PR15131. --- pkgs/racket-doc/scribblings/guide/module-set.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/guide/module-set.scrbl b/pkgs/racket-doc/scribblings/guide/module-set.scrbl index ef0a59c235..55bbd9ce3e 100644 --- a/pkgs/racket-doc/scribblings/guide/module-set.scrbl +++ b/pkgs/racket-doc/scribblings/guide/module-set.scrbl @@ -34,7 +34,7 @@ modular reasoning about programs. For example, in the module, (provide rx:fish fishy-string?) (define rx:fish #rx"fish") (define (fishy-string? s) - (regexp-match? s rx:fish))) + (regexp-match? rx:fish s))) ] the function @racket[fishy-string?] will always match strings that From fbe8537f18aa1b466c6b0c2106028444cc4484a1 Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Mon, 10 Aug 2015 14:34:07 -0600 Subject: [PATCH 013/381] add `compiled-expression-recompile` Uses an unresolver pass, which is expanded to work on more programs. --- .../scribblings/reference/eval.scrbl | 12 + racket/src/racket/mk-gdbinit.rkt | 114 +- racket/src/racket/src/compenv.c | 31 +- racket/src/racket/src/cstartup.inc | 1324 ++++++++-------- racket/src/racket/src/eval.c | 118 +- racket/src/racket/src/jit.c | 8 +- racket/src/racket/src/marshal.c | 8 +- racket/src/racket/src/mzmark_resolve.inc | 12 + racket/src/racket/src/mzmarksrc.c | 6 + racket/src/racket/src/resolve.c | 1406 ++++++++++++++++- racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schpriv.h | 11 +- racket/src/racket/src/schvers.h | 4 +- racket/src/racket/src/validate.c | 8 +- 14 files changed, 2291 insertions(+), 773 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/eval.scrbl b/pkgs/racket-doc/scribblings/reference/eval.scrbl index 79f752b577..4b37eea3e1 100644 --- a/pkgs/racket-doc/scribblings/reference/eval.scrbl +++ b/pkgs/racket-doc/scribblings/reference/eval.scrbl @@ -484,6 +484,18 @@ Like @racket[eval-syntax], but calls the current @tech{compilation handler} in tail position with @racket[stx].} +@defproc[(compiled-expression-recompile [ce compiled-expression?]) compiled-expression?]{ + +Recompiles @racket[ce], effectively re-running optimization passes to +produce an equivalent compiled form with potentially different +performance characteristics. + +If @racket[ce] includes module forms, then only phase-0 code in the +immediate module (not in submodules) is recompiled. + +@history[#:added "6.2.900.9"]} + + @defproc[(compiled-expression? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a compiled form, @racket[#f] diff --git a/racket/src/racket/mk-gdbinit.rkt b/racket/src/racket/mk-gdbinit.rkt index 713df4479f..6867800f4e 100644 --- a/racket/src/racket/mk-gdbinit.rkt +++ b/racket/src/racket/mk-gdbinit.rkt @@ -73,6 +73,10 @@ define psoq set $TL = ((Scheme_Toplevel*) ($O)) printf "scheme_toplevel_type depth=%d position=%d", $TL->depth, $TL->position end + if ( $OT == <> ) + set $local = ((Scheme_Local *) ($O)) + printf "scheme_local position=%d", $local->position + end # if ( $OT == <> ) # set $SSO = ((Scheme_Simple_Object*) ($O)) # set $index = $SSO->u.ptr_int_val.pint @@ -86,11 +90,11 @@ define psoq printf "scheme_application_type - args %i\n", $size set $RATOR = $AP->args[0] indent $arg1 - printf "rator=" - psox $RATOR $arg1+1 - + printf "rator = " + psonn $RATOR + printf "\n" set $cnt = 1 - while ( $cnt < $size ) + while ( $cnt <= $size ) indent $arg1 printf "rand%i = ", ($cnt - 1) psonn $AP->args[$cnt] @@ -135,7 +139,85 @@ define psoq psox $unclosure->code $arg1+1 set $OT = <> end - + if ( $OT == <> ) + set $unclosure = ((Scheme_Closure_Data *) $O) + #set $name = $code->name + set $param_num = $unclosure->num_params + printf "scheme_compiled_unclosed_procedure_type - num_params %i\n", $param_num + psox $unclosure->code $arg1+1 + end + if ( $OT == <> ) + set $let_value = ((Scheme_Let_Value *) $O) + set $cnt = $let_value->count + set $pos = $let_value->position + set $val = $let_value->value + set $body = $let_value->body + printf "scheme_let_value\n" + indent $arg1 + printf "count = %i\n", $cnt + indent $arg1 + printf "position = %i\n", $pos + psox $val $arg1+1 + printf "\n" + psox $body $arg1+1 + printf "\n" + end + if ( $OT == <> ) + set $let_void = ((Scheme_Let_Void *) $O) + set $cnt = $let_void->count + set $body = $let_void->body + printf "scheme_let_void\n" + indent $arg1 + printf "count = %i\n", $cnt + indent $arg1 + printf "body = " + psox $body $arg1+1 + printf "\n" + end + if ( $OT == <> ) + set $let_header = ((Scheme_Let_Header *) $O) + set $cnt = $let_header->count + set $clauses = $let_header->num_clauses + set $body = $let_header->body + printf "scheme_let_header\n" + indent $arg1 + printf "count = %i, num_clauses = %i\n", $cnt, $clauses + indent $arg1 + printf "body = " + psox $body $arg1+1 + printf "\n" + end + if ( $OT == <> ) + set $let_value = ((Scheme_Compiled_Let_Value *) $O) + set $cnt = $let_value->count + set $pos = $let_value->position + set $val = $let_value->value + set $body = $let_value->body + printf "scheme_compiled_let_value\n" + indent $arg1 + printf "count = %i, position = %i\n", $cnt, $pos + indent $arg1 + printf "value =\n" + psox $val $arg1+1 + printf "\n" + indent $arg1 + printf "body =\n" + psox $body $arg1+1 + printf "\n" + end + if ( $OT == <> ) + set $sb = ((Scheme_Set_Bang *) $O) + set $var = $sb->var + set $val = $sb->val + printf "scheme_set_bang\n" + indent $arg1 + printf "var = " + psox $var $arg1+1 + printf "\n" + printf "val = " + psox $val $arg1+1 + printf "\n" + end if ( $OT == <> ) set $seq = ((Scheme_Sequence *) $O) set $size = $seq->count @@ -151,6 +233,21 @@ define psoq end set $OT = 0 end + if ( $OT == <> ) + set $seq = ((Scheme_Sequence *) $O) + set $size = $seq->count + printf "scheme_begin0_sequence - size %i\n", $size + set $cnt = 0 + while ( $cnt < $size ) + indent $arg1 + printf "%i - ", $cnt + psonn $seq->array[$cnt] + printf "\n" + #psox $seq->array[$cnt] $arg1+2 + set $cnt++ + end + set $OT = 0 + end if ( $OT == <>) set $breq = ((Scheme_Branch_Rec *) $O) printf "scheme_branch_type\n" @@ -185,6 +282,13 @@ define psoq indent $arg1+1 printf "body %p\n", $letone->body end + if ( $OT == <> ) + set $box = ((Scheme_Simple_Object *) $O) + printf "scheme_boxenv_type\n" + psox $box->u.two_ptr_val.ptr1 $arg1+1 + printf "\n" + psox $box->u.two_ptr_val.ptr2 $arg1+1 + end if ( $OT == <> ) printf "scheme_closure_type\n" set $closure = ((Scheme_Closure *) $O) diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index 4fac159c22..5ba2ade4c9 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -730,23 +730,12 @@ Scheme_Object *scheme_toplevel_to_flagged_toplevel(Scheme_Object *_tl, int flags return scheme_make_toplevel(tl->depth, tl->position, 0, flags); } -Scheme_Object *scheme_register_stx_in_prefix(Scheme_Object *var, Scheme_Comp_Env *env, - Scheme_Compile_Info *rec, int drec) +Scheme_Object *scheme_register_stx_in_comp_prefix(Scheme_Object *var, Comp_Prefix *cp) { - Comp_Prefix *cp = env->prefix; Scheme_Local *l; Scheme_Object *o; int pos; - if (rec && rec[drec].dont_mark_local_use) { - /* Make up anything; it's going to be ignored. */ - l = (Scheme_Local *)scheme_malloc_atomic_tagged(sizeof(Scheme_Local)); - l->iso.so.type = scheme_compiled_quote_syntax_type; - l->position = 0; - - return (Scheme_Object *)l; - } - if (!cp->stxes) { Scheme_Hash_Table *ht; ht = scheme_make_hash_table(SCHEME_hash_ptr); @@ -767,6 +756,24 @@ Scheme_Object *scheme_register_stx_in_prefix(Scheme_Object *var, Scheme_Comp_Env return o; } +Scheme_Object *scheme_register_stx_in_prefix(Scheme_Object *var, Scheme_Comp_Env *env, + Scheme_Compile_Info *rec, int drec) +{ + Scheme_Local *l; + Comp_Prefix *cp = env->prefix; + + if (rec && rec[drec].dont_mark_local_use) { + /* Make up anything; it's going to be ignored. */ + l = (Scheme_Local *)scheme_malloc_atomic_tagged(sizeof(Scheme_Local)); + l->iso.so.type = scheme_compiled_quote_syntax_type; + l->position = 0; + + return (Scheme_Object *)l; + } + + return scheme_register_stx_in_comp_prefix(var, cp); +} + /*========================================================================*/ /* compile-time env, lookup bindings */ /*========================================================================*/ diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index 7f2b33898f..b486bc703a 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,5 +1,5 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,0,1,0,0,8,0, 18,0,22,0,26,0,31,0,38,0,42,0,47,0,59,0,66,0,69,0,82, 0,89,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159,0, @@ -29,50 +29,50 @@ 22,90,2,19,248,22,102,199,12,249,22,80,2,20,248,22,104,201,27,248,22, 164,4,195,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,102,199,249, 22,80,2,20,248,22,104,201,12,27,248,22,82,248,22,164,4,196,28,248,22, -88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,161,20,193, -249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,161,20,199,249,22,80, -2,4,248,22,162,20,201,11,18,143,10,2,28,27,248,22,82,248,22,164,4, +88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,162,20,193, +249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,162,20,199,249,22,80, +2,4,248,22,163,20,201,11,18,143,10,2,28,27,248,22,82,248,22,164,4, 196,28,248,22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248, -22,161,20,193,249,22,157,4,80,143,42,39,250,22,90,2,21,248,22,90,249, -22,90,248,22,90,2,22,248,22,161,20,201,251,22,90,2,19,2,22,2,22, -249,22,80,2,11,248,22,162,20,204,18,143,11,2,28,248,22,164,4,193,27, -248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22,162,20,195,27, +22,162,20,193,249,22,157,4,80,143,42,39,250,22,90,2,21,248,22,90,249, +22,90,248,22,90,2,22,248,22,162,20,201,251,22,90,2,19,2,22,2,22, +249,22,80,2,11,248,22,163,20,204,18,143,11,2,28,248,22,164,4,193,27, +248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22,163,20,195,27, 248,22,82,248,22,164,4,23,197,1,249,22,157,4,80,143,42,39,28,248,22, 64,248,22,158,4,248,22,81,23,198,2,27,249,22,2,32,0,88,148,8,36, 40,46,11,9,222,33,43,248,22,164,4,248,22,102,23,200,2,250,22,90,2, -23,248,22,90,249,22,90,248,22,90,248,22,161,20,23,204,2,250,22,91,2, -24,249,22,2,22,81,23,204,2,248,22,104,23,206,2,249,22,80,248,22,161, +23,248,22,90,249,22,90,248,22,90,248,22,162,20,23,204,2,250,22,91,2, +24,249,22,2,22,81,23,204,2,248,22,104,23,206,2,249,22,80,248,22,162, 20,23,202,1,249,22,2,22,102,23,200,1,250,22,91,2,21,249,22,2,32, -0,88,148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,161,20,201, -248,22,162,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196, -248,22,162,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80, +0,88,148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,162,20,201, +248,22,163,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196, +248,22,163,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80, 143,42,39,250,22,91,2,23,249,22,2,32,0,88,148,8,36,40,50,11,9, -222,33,46,248,22,164,4,248,22,81,201,248,22,162,20,198,27,248,22,82,248, +222,33,46,248,22,164,4,248,22,81,201,248,22,163,20,198,27,248,22,82,248, 22,164,4,196,27,248,22,164,4,248,22,81,195,249,22,157,4,80,143,43,39, -28,248,22,88,195,250,22,91,2,21,9,248,22,162,20,199,250,22,90,2,7, -248,22,90,248,22,81,199,250,22,91,2,8,248,22,162,20,201,248,22,162,20, +28,248,22,88,195,250,22,91,2,21,9,248,22,163,20,199,250,22,90,2,7, +248,22,90,248,22,81,199,250,22,91,2,8,248,22,163,20,201,248,22,163,20, 202,27,248,22,82,248,22,164,4,196,27,248,22,164,4,248,22,81,195,249,22, -157,4,80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,162,20, -199,250,22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,162, -20,201,248,22,162,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249,22, +157,4,80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,163,20, +199,250,22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,163, +20,201,248,22,163,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249,22, 1,22,94,249,22,2,22,164,4,248,22,164,4,248,22,81,199,248,22,185,4, 249,22,157,4,80,143,44,39,251,22,90,1,22,119,105,116,104,45,99,111,110, 116,105,110,117,97,116,105,111,110,45,109,97,114,107,2,25,250,22,91,1,23, 101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105, 111,110,21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97, 114,107,45,115,101,116,45,102,105,114,115,116,11,2,25,202,250,22,91,2,21, -9,248,22,162,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193,20, +9,248,22,163,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193,20, 14,144,40,39,40,249,22,157,4,80,143,42,39,27,248,22,164,4,248,22,81, 197,28,249,22,169,9,64,61,62,248,22,158,4,248,22,102,196,250,22,90,2, -21,248,22,90,249,22,90,21,93,2,26,248,22,161,20,199,250,22,91,2,5, -249,22,90,2,26,249,22,90,248,22,111,203,2,26,248,22,162,20,202,251,22, -90,2,19,28,249,22,169,9,248,22,158,4,248,22,161,20,200,66,101,108,115, -101,10,248,22,161,20,197,250,22,91,2,21,9,248,22,162,20,200,249,22,80, -2,5,248,22,162,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22, +21,248,22,90,249,22,90,21,93,2,26,248,22,162,20,199,250,22,91,2,5, +249,22,90,2,26,249,22,90,248,22,111,203,2,26,248,22,163,20,202,251,22, +90,2,19,28,249,22,169,9,248,22,158,4,248,22,162,20,200,66,101,108,115, +101,10,248,22,162,20,197,250,22,91,2,21,9,248,22,163,20,200,249,22,80, +2,5,248,22,163,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22, 82,248,22,164,4,196,249,22,157,4,80,143,42,39,28,248,22,64,248,22,158, -4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,161,20,199,248,22,102, -198,27,248,22,158,4,248,22,161,20,197,250,22,90,2,27,248,22,90,248,22, -81,197,250,22,91,2,24,248,22,162,20,199,248,22,162,20,202,144,39,20,121, +4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,162,20,199,248,22,102, +198,27,248,22,158,4,248,22,162,20,197,250,22,90,2,27,248,22,90,248,22, +81,197,250,22,91,2,24,248,22,163,20,199,248,22,163,20,202,144,39,20,121, 145,2,1,39,16,1,11,16,0,20,27,15,61,9,2,2,2,2,2,3,11, 11,11,11,9,9,11,11,11,10,39,80,143,39,39,20,121,145,2,1,39,16, 0,16,0,41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4,2,5, @@ -102,7 +102,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 2091); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,1,0,0,8,0, 16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,178,0,193, 0,211,0,223,0,239,0,253,0,19,1,39,1,73,1,90,1,107,1,130,1, @@ -185,292 +185,292 @@ 114,111,111,116,32,112,97,116,104,58,32,68,102,105,110,105,115,104,5,11,80, 76,84,67,79,76,76,69,67,84,83,1,20,99,111,108,108,101,99,116,115,45, 115,101,97,114,99,104,45,100,105,114,115,6,8,8,99,111,108,108,101,99,116, -115,27,248,22,173,15,194,28,192,192,28,248,22,153,7,194,27,248,22,132,16, -195,28,192,192,248,22,133,16,195,11,0,21,35,114,120,34,94,91,92,92,93, +115,27,248,22,174,15,194,28,192,192,28,248,22,153,7,194,27,248,22,133,16, +195,28,192,192,248,22,134,16,195,11,0,21,35,114,120,34,94,91,92,92,93, 91,92,92,93,91,63,93,91,92,92,93,34,0,6,35,114,120,34,47,34,0, 22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91,47,92,92,93,42, 36,34,0,19,35,114,120,34,91,32,46,93,43,40,91,47,92,92,93,42,41, -36,34,86,94,28,28,248,22,174,15,23,195,2,10,28,248,22,173,15,23,195, -2,10,28,248,22,153,7,23,195,2,28,248,22,132,16,23,195,2,10,248,22, -133,16,23,195,2,11,12,250,22,180,11,2,41,2,42,23,197,2,28,28,248, -22,174,15,23,195,2,249,22,169,9,248,22,175,15,23,197,2,2,43,249,22, +36,34,86,94,28,28,248,22,175,15,23,195,2,10,28,248,22,174,15,23,195, +2,10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22, +134,16,23,195,2,11,12,250,22,181,11,2,41,2,42,23,197,2,28,28,248, +22,175,15,23,195,2,249,22,169,9,248,22,176,15,23,197,2,2,43,249,22, 169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,196,2,23,195,2,248, -22,165,8,248,22,178,15,23,197,2,28,249,22,170,16,2,79,23,195,2,28, -248,22,153,7,195,248,22,181,15,195,194,27,248,22,128,8,23,195,1,249,22, -182,15,248,22,168,8,250,22,178,16,2,80,28,249,22,170,16,2,81,23,201, -2,23,199,1,250,22,178,16,2,82,23,202,1,2,44,80,144,47,40,41,2, -43,28,248,22,153,7,194,248,22,181,15,194,193,0,28,35,114,120,34,94,92, +22,165,8,248,22,179,15,23,197,2,28,249,22,171,16,2,79,23,195,2,28, +248,22,153,7,195,248,22,182,15,195,194,27,248,22,128,8,23,195,1,249,22, +183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171,16,2,81,23,201, +2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80,144,47,40,41,2, +43,28,248,22,153,7,194,248,22,182,15,194,193,0,28,35,114,120,34,94,92, 92,92,92,92,92,92,92,91,63,93,92,92,92,92,85,78,67,92,92,92,92, -34,86,95,28,28,28,248,22,173,15,23,195,2,10,28,248,22,153,7,23,195, -2,28,248,22,132,16,23,195,2,10,248,22,133,16,23,195,2,11,10,248,22, -174,15,23,195,2,12,252,22,180,11,2,6,2,45,39,23,199,2,23,200,2, -28,28,28,248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248, -22,132,16,23,196,2,10,248,22,133,16,23,196,2,11,10,248,22,174,15,23, -196,2,12,252,22,180,11,2,6,2,45,40,23,199,2,23,200,2,27,28,248, -22,174,15,23,196,2,248,22,175,15,23,196,2,247,22,176,15,86,95,28,28, -248,22,134,16,23,196,2,10,249,22,169,9,247,22,176,15,23,195,2,12,253, -22,182,11,2,6,6,54,54,112,97,116,104,32,105,115,32,110,111,116,32,99, +34,86,95,28,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195, +2,28,248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,10,248,22, +175,15,23,195,2,12,252,22,181,11,2,6,2,45,39,23,199,2,23,200,2, +28,28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248, +22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,10,248,22,175,15,23, +196,2,12,252,22,181,11,2,6,2,45,40,23,199,2,23,200,2,27,28,248, +22,175,15,23,196,2,248,22,176,15,23,196,2,247,22,177,15,86,95,28,28, +248,22,135,16,23,196,2,10,249,22,169,9,247,22,177,15,23,195,2,12,253, +22,183,11,2,6,6,54,54,112,97,116,104,32,105,115,32,110,111,116,32,99, 111,109,112,108,101,116,101,32,97,110,100,32,110,111,116,32,116,104,101,32,112, 108,97,116,102,111,114,109,39,115,32,99,111,110,118,101,110,116,105,111,110,2, 46,23,201,2,6,24,24,112,108,97,116,102,111,114,109,32,99,111,110,118,101, -110,116,105,111,110,32,116,121,112,101,247,22,176,15,28,249,22,169,9,28,248, -22,174,15,23,199,2,248,22,175,15,23,199,2,247,22,176,15,23,195,2,12, -253,22,182,11,2,6,6,37,37,103,105,118,101,110,32,112,97,116,104,115,32, +110,116,105,111,110,32,116,121,112,101,247,22,177,15,28,249,22,169,9,28,248, +22,175,15,23,199,2,248,22,176,15,23,199,2,247,22,177,15,23,195,2,12, +253,22,183,11,2,6,6,37,37,103,105,118,101,110,32,112,97,116,104,115,32, 117,115,101,32,100,105,102,102,101,114,101,110,116,32,99,111,110,118,101,110,116, 105,111,110,115,2,46,23,201,2,6,9,9,114,111,111,116,32,112,97,116,104, -23,202,2,27,27,248,22,138,16,28,248,22,134,16,23,199,2,23,198,1,248, -22,135,16,23,199,1,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22, -173,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,132,16,23,194, -2,10,248,22,133,16,23,194,2,11,12,250,22,180,11,2,41,2,42,23,196, -2,28,28,248,22,174,15,23,194,2,249,22,169,9,248,22,175,15,23,196,2, +23,202,2,27,27,248,22,139,16,28,248,22,135,16,23,199,2,23,198,1,248, +22,136,16,23,199,1,86,94,28,28,248,22,175,15,23,194,2,10,28,248,22, +174,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,133,16,23,194, +2,10,248,22,134,16,23,194,2,11,12,250,22,181,11,2,41,2,42,23,196, +2,28,28,248,22,175,15,23,194,2,249,22,169,9,248,22,176,15,23,196,2, 2,43,249,22,169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,195,2, -23,194,2,248,22,165,8,248,22,178,15,23,196,2,28,249,22,170,16,2,79, -23,195,2,28,248,22,153,7,194,248,22,181,15,194,193,27,248,22,128,8,23, -195,1,249,22,182,15,248,22,168,8,250,22,178,16,2,80,28,249,22,170,16, -2,81,23,201,2,23,199,1,250,22,178,16,2,82,23,202,1,2,44,80,144, -50,40,41,2,43,28,248,22,153,7,193,248,22,181,15,193,192,27,248,22,178, +23,194,2,248,22,165,8,248,22,179,15,23,196,2,28,249,22,171,16,2,79, +23,195,2,28,248,22,153,7,194,248,22,182,15,194,193,27,248,22,128,8,23, +195,1,249,22,183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171,16, +2,81,23,201,2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80,144, +50,40,41,2,43,28,248,22,153,7,193,248,22,182,15,193,192,27,248,22,179, 15,23,195,2,28,249,22,169,9,23,197,2,66,117,110,105,120,28,249,22,150, -8,194,5,1,47,28,248,22,174,15,198,197,248,22,181,15,198,249,22,191,15, -199,249,22,182,15,249,22,153,8,248,22,178,15,200,40,198,28,249,22,169,9, -23,197,2,2,43,249,22,191,15,23,200,1,249,22,182,15,28,249,22,170,16, +8,194,5,1,47,28,248,22,175,15,198,197,248,22,182,15,198,249,22,128,16, +199,249,22,183,15,249,22,153,8,248,22,179,15,200,40,198,28,249,22,169,9, +23,197,2,2,43,249,22,128,16,23,200,1,249,22,183,15,28,249,22,171,16, 0,27,35,114,120,34,94,92,92,92,92,92,92,92,92,91,63,93,92,92,92, 92,91,97,45,122,93,58,34,23,199,2,251,22,154,8,2,47,250,22,153,8, -203,43,44,5,1,92,249,22,153,8,202,45,28,249,22,170,16,2,84,23,199, -2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,170,16,2,84,23, -199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,170,16,0,14, +203,43,44,5,1,92,249,22,153,8,202,45,28,249,22,171,16,2,84,23,199, +2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,2,84,23, +199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,0,14, 35,114,120,34,94,92,92,92,92,92,92,92,92,34,23,199,2,249,22,154,8, -5,4,85,78,67,92,249,22,153,8,200,41,28,249,22,170,16,0,12,35,114, +5,4,85,78,67,92,249,22,153,8,200,41,28,249,22,171,16,0,12,35,114, 120,34,94,91,97,45,122,93,58,34,198,249,22,154,8,250,22,153,8,201,39, 40,249,22,153,8,200,41,12,198,12,32,86,88,148,8,36,42,56,11,72,102, 111,117,110,100,45,101,120,101,99,222,33,89,32,87,88,148,8,36,43,61,11, -66,110,101,120,116,222,33,88,27,248,22,136,16,23,196,2,28,249,22,171,9, -23,195,2,23,197,1,11,28,248,22,132,16,23,194,2,27,249,22,191,15,23, -197,1,23,196,1,28,23,197,2,90,144,42,11,89,146,42,39,11,248,22,130, -16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,2,27,248,22,136, -16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28,248,22,132,16, -23,194,2,250,2,86,23,205,2,23,206,2,249,22,191,15,23,200,2,23,198, +66,110,101,120,116,222,33,88,27,248,22,137,16,23,196,2,28,249,22,171,9, +23,195,2,23,197,1,11,28,248,22,133,16,23,194,2,27,249,22,128,16,23, +197,1,23,196,1,28,23,197,2,90,144,42,11,89,146,42,39,11,248,22,131, +16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,2,27,248,22,137, +16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28,248,22,133,16, +23,194,2,250,2,86,23,205,2,23,206,2,249,22,128,16,23,200,2,23,198, 1,250,2,86,23,205,2,23,206,2,23,196,1,11,28,23,193,2,192,86,94, -23,193,1,27,28,248,22,173,15,23,196,2,27,249,22,191,15,23,198,2,23, -205,2,28,28,248,22,186,15,193,10,248,22,185,15,193,192,11,11,28,23,193, -2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,136,16,23,200,2,28, -249,22,171,9,194,23,201,1,11,28,248,22,132,16,193,250,2,86,205,206,249, -22,191,15,200,197,250,2,86,205,206,195,192,86,94,23,194,1,28,23,196,2, -90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,2,86,95,23,195,1, -23,194,1,27,28,23,201,2,27,248,22,136,16,23,199,2,28,249,22,171,9, -23,195,2,23,200,2,11,28,248,22,132,16,23,194,2,250,2,86,23,204,2, -23,205,2,249,22,191,15,23,200,2,23,198,1,250,2,86,23,204,2,23,205, -2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,173,15, -23,196,2,27,249,22,191,15,23,198,2,23,204,2,28,28,248,22,186,15,193, -10,248,22,185,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28,23, -202,2,11,27,248,22,136,16,23,200,2,28,249,22,171,9,194,23,201,1,11, -28,248,22,132,16,193,250,2,86,204,205,249,22,191,15,200,197,250,2,86,204, -205,195,192,28,23,193,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23, +23,193,1,27,28,248,22,174,15,23,196,2,27,249,22,128,16,23,198,2,23, +205,2,28,28,248,22,187,15,193,10,248,22,186,15,193,192,11,11,28,23,193, +2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,137,16,23,200,2,28, +249,22,171,9,194,23,201,1,11,28,248,22,133,16,193,250,2,86,205,206,249, +22,128,16,200,197,250,2,86,205,206,195,192,86,94,23,194,1,28,23,196,2, +90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,2,86,95,23,195,1, +23,194,1,27,28,23,201,2,27,248,22,137,16,23,199,2,28,249,22,171,9, +23,195,2,23,200,2,11,28,248,22,133,16,23,194,2,250,2,86,23,204,2, +23,205,2,249,22,128,16,23,200,2,23,198,1,250,2,86,23,204,2,23,205, +2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,174,15, +23,196,2,27,249,22,128,16,23,198,2,23,204,2,28,28,248,22,187,15,193, +10,248,22,186,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28,23, +202,2,11,27,248,22,137,16,23,200,2,28,249,22,171,9,194,23,201,1,11, +28,248,22,133,16,193,250,2,86,204,205,249,22,128,16,200,197,250,2,86,204, +205,195,192,28,23,193,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23, 199,2,86,95,23,195,1,23,194,1,27,28,23,198,2,251,2,87,23,198,2, 23,203,2,23,201,2,23,202,2,11,28,23,193,2,192,86,94,23,193,1,27, -28,248,22,173,15,195,27,249,22,191,15,197,200,28,28,248,22,186,15,193,10, -248,22,185,15,193,192,11,11,28,192,192,28,198,11,251,2,87,198,203,201,202, +28,248,22,174,15,195,27,249,22,128,16,197,200,28,28,248,22,187,15,193,10, +248,22,186,15,193,192,11,11,28,192,192,28,198,11,251,2,87,198,203,201,202, 194,32,90,88,148,8,36,43,60,11,2,50,222,33,91,28,248,22,88,23,197, -2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,201,2,23,196,2,28, -248,22,185,15,23,194,2,250,2,86,197,198,195,86,94,23,193,1,27,248,22, -162,20,23,199,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22,135, -16,248,22,81,23,198,2,23,198,2,28,248,22,185,15,23,194,2,250,2,86, -199,200,195,86,94,23,193,1,27,248,22,162,20,23,196,1,28,248,22,88,23, -194,2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,198,2,23,200,2, -28,248,22,185,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248, -22,162,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22, -135,16,248,22,81,197,201,28,248,22,185,15,193,250,2,86,203,204,195,251,2, -90,203,204,205,248,22,162,20,198,86,95,28,28,248,22,173,15,23,195,2,10, -28,248,22,153,7,23,195,2,28,248,22,132,16,23,195,2,10,248,22,133,16, -23,195,2,11,12,250,22,180,11,2,7,2,48,23,197,2,28,28,23,195,2, -28,28,248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22, -132,16,23,196,2,10,248,22,133,16,23,196,2,11,248,22,132,16,23,196,2, -11,10,12,250,22,180,11,2,7,6,45,45,40,111,114,47,99,32,35,102,32, +2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,201,2,23,196,2,28, +248,22,186,15,23,194,2,250,2,86,197,198,195,86,94,23,193,1,27,248,22, +163,20,23,199,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22,136, +16,248,22,81,23,198,2,23,198,2,28,248,22,186,15,23,194,2,250,2,86, +199,200,195,86,94,23,193,1,27,248,22,163,20,23,196,1,28,248,22,88,23, +194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,200,2, +28,248,22,186,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248, +22,163,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, +136,16,248,22,81,197,201,28,248,22,186,15,193,250,2,86,203,204,195,251,2, +90,203,204,205,248,22,163,20,198,86,95,28,28,248,22,174,15,23,195,2,10, +28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134,16, +23,195,2,11,12,250,22,181,11,2,7,2,48,23,197,2,28,28,23,195,2, +28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22, +133,16,23,196,2,10,248,22,134,16,23,196,2,11,248,22,133,16,23,196,2, +11,10,12,250,22,181,11,2,7,6,45,45,40,111,114,47,99,32,35,102,32, 40,97,110,100,47,99,32,112,97,116,104,45,115,116,114,105,110,103,63,32,114, 101,108,97,116,105,118,101,45,112,97,116,104,63,41,41,23,198,2,28,28,248, -22,132,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,198, +22,133,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,198, 2,249,22,169,9,194,2,49,11,27,249,22,175,8,247,22,174,8,5,4,80, 65,84,72,27,28,23,194,2,249,80,143,43,44,249,22,165,8,23,198,1,7, 63,9,86,94,23,194,1,9,27,28,249,22,169,9,247,22,180,8,2,43,249, -22,80,248,22,182,15,5,1,46,23,196,1,23,194,1,28,248,22,88,23,194, -2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,198,2,23,200,2,28, -248,22,185,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248,22, -162,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22,135, -16,248,22,81,23,198,2,23,202,2,28,248,22,185,15,23,194,2,250,2,86, -203,204,195,86,94,23,193,1,27,248,22,162,20,23,196,1,28,248,22,88,23, -194,2,11,27,249,22,191,15,248,22,135,16,248,22,81,23,198,2,23,204,2, -28,248,22,185,15,23,194,2,250,2,86,205,206,195,86,94,23,193,1,27,248, -22,162,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,191,15,248,22, -135,16,248,22,81,197,205,28,248,22,185,15,193,250,2,86,23,15,23,16,195, -251,2,90,23,15,23,16,23,17,248,22,162,20,198,27,248,22,135,16,23,196, -1,28,248,22,185,15,193,250,2,86,198,199,195,11,250,80,144,42,43,42,196, +22,80,248,22,183,15,5,1,46,23,196,1,23,194,1,28,248,22,88,23,194, +2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,200,2,28, +248,22,186,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248,22, +163,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22,136, +16,248,22,81,23,198,2,23,202,2,28,248,22,186,15,23,194,2,250,2,86, +203,204,195,86,94,23,193,1,27,248,22,163,20,23,196,1,28,248,22,88,23, +194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,204,2, +28,248,22,186,15,23,194,2,250,2,86,205,206,195,86,94,23,193,1,27,248, +22,163,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, +136,16,248,22,81,197,205,28,248,22,186,15,193,250,2,86,23,15,23,16,195, +251,2,90,23,15,23,16,23,17,248,22,163,20,198,27,248,22,136,16,23,196, +1,28,248,22,186,15,193,250,2,86,198,199,195,11,250,80,144,42,43,42,196, 197,11,250,80,144,42,43,42,196,11,11,32,95,88,148,8,36,42,58,11,2, -50,222,33,97,0,8,35,114,120,35,34,92,34,34,27,249,22,166,16,23,197, +50,222,33,97,0,8,35,114,120,35,34,92,34,34,27,249,22,167,16,23,197, 2,23,198,2,28,23,193,2,86,94,23,196,1,27,248,22,102,23,195,2,27, -27,248,22,111,23,197,1,27,249,22,166,16,23,201,2,23,196,2,28,23,193, +27,248,22,111,23,197,1,27,249,22,167,16,23,201,2,23,196,2,28,23,193, 2,86,94,23,194,1,27,248,22,102,23,195,2,27,250,2,95,202,23,204,1, -248,22,111,23,199,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22,178, +248,22,111,23,199,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22,179, 16,2,96,23,198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,202, -195,249,22,80,248,22,182,15,195,195,86,95,23,199,1,23,193,1,27,28,249, -22,169,9,247,22,180,8,2,43,250,22,178,16,2,96,23,198,1,2,51,194, -28,249,22,150,8,194,2,51,249,22,94,200,9,249,22,80,248,22,182,15,195, -9,27,28,249,22,169,9,247,22,180,8,2,43,250,22,178,16,2,96,23,198, +195,249,22,80,248,22,183,15,195,195,86,95,23,199,1,23,193,1,27,28,249, +22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23,198,1,2,51,194, +28,249,22,150,8,194,2,51,249,22,94,200,9,249,22,80,248,22,183,15,195, +9,27,28,249,22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23,198, 1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,198,195,249,22,80,248, -22,182,15,195,195,86,94,23,193,1,27,28,249,22,169,9,247,22,180,8,2, -43,250,22,178,16,2,96,23,200,1,2,51,196,28,249,22,150,8,194,2,51, -249,22,94,196,9,249,22,80,248,22,182,15,195,9,86,95,28,28,248,22,142, -8,194,10,248,22,153,7,194,12,250,22,180,11,2,8,6,21,21,40,111,114, +22,183,15,195,195,86,94,23,193,1,27,28,249,22,169,9,247,22,180,8,2, +43,250,22,179,16,2,96,23,200,1,2,51,196,28,249,22,150,8,194,2,51, +249,22,94,196,9,249,22,80,248,22,183,15,195,9,86,95,28,28,248,22,142, +8,194,10,248,22,153,7,194,12,250,22,181,11,2,8,6,21,21,40,111,114, 47,99,32,98,121,116,101,115,63,32,115,116,114,105,110,103,63,41,196,28,28, -248,22,89,195,249,22,4,22,173,15,196,11,12,250,22,180,11,2,8,6,14, +248,22,89,195,249,22,4,22,174,15,196,11,12,250,22,181,11,2,8,6,14, 14,40,108,105,115,116,111,102,32,112,97,116,104,63,41,197,250,2,95,197,195, 28,248,22,153,7,197,248,22,167,8,197,196,28,28,248,22,0,23,195,2,249, 22,48,23,196,2,39,11,20,13,144,80,144,39,46,40,26,29,80,144,8,29, -47,40,249,22,31,11,80,144,8,31,46,40,22,143,15,10,22,144,15,10,22, -145,15,10,22,148,15,10,22,147,15,11,22,149,15,10,22,146,15,10,22,150, -15,10,22,151,15,10,22,152,15,10,22,153,15,10,22,154,15,11,22,155,15, -10,22,141,15,11,247,23,194,1,250,22,180,11,2,9,2,52,23,197,1,86, -94,28,28,248,22,173,15,23,195,2,10,28,248,22,153,7,23,195,2,28,248, -22,132,16,23,195,2,10,248,22,133,16,23,195,2,11,12,250,22,180,11,23, -196,2,2,48,23,197,2,28,248,22,132,16,23,195,2,12,251,22,182,11,23, -197,1,2,53,2,46,23,198,1,86,94,28,28,248,22,173,15,23,195,2,10, -28,248,22,153,7,23,195,2,28,248,22,132,16,23,195,2,10,248,22,133,16, -23,195,2,11,12,250,22,180,11,23,196,2,2,48,23,197,2,28,248,22,132, -16,23,195,2,12,251,22,182,11,23,197,1,2,53,2,46,23,198,1,86,94, -86,94,28,28,248,22,173,15,23,195,2,10,28,248,22,153,7,23,195,2,28, -248,22,132,16,23,195,2,10,248,22,133,16,23,195,2,11,12,250,22,180,11, -23,196,2,2,48,23,197,2,28,248,22,132,16,23,195,2,86,94,23,194,1, -12,251,22,182,11,23,197,2,2,53,2,46,23,198,1,249,22,3,20,20,94, +47,40,249,22,31,11,80,144,8,31,46,40,22,144,15,10,22,145,15,10,22, +146,15,10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22,151, +15,10,22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156,15, +10,22,142,15,11,247,23,194,1,250,22,181,11,2,9,2,52,23,197,1,86, +94,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195,2,28,248, +22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,12,250,22,181,11,23, +196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,12,251,22,183,11,23, +197,1,2,53,2,46,23,198,1,86,94,28,28,248,22,174,15,23,195,2,10, +28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134,16, +23,195,2,11,12,250,22,181,11,23,196,2,2,48,23,197,2,28,248,22,133, +16,23,195,2,12,251,22,183,11,23,197,1,2,53,2,46,23,198,1,86,94, +86,94,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195,2,28, +248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,12,250,22,181,11, +23,196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,86,94,23,194,1, +12,251,22,183,11,23,197,2,2,53,2,46,23,198,1,249,22,3,20,20,94, 88,148,8,36,40,50,11,9,223,2,33,101,23,195,1,23,197,1,28,28,248, -22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22,180,11,23,196,1, -2,54,23,197,1,86,94,28,28,248,22,173,15,23,194,2,10,28,248,22,153, -7,23,194,2,28,248,22,132,16,23,194,2,10,248,22,133,16,23,194,2,11, -12,250,22,180,11,2,15,2,48,23,196,2,28,248,22,132,16,23,194,2,12, -251,22,182,11,2,15,2,53,2,46,23,197,1,86,95,86,94,86,94,28,28, -248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,132,16, -23,196,2,10,248,22,133,16,23,196,2,11,12,250,22,180,11,2,15,2,48, -23,198,2,28,248,22,132,16,23,196,2,12,251,22,182,11,2,15,2,53,2, +22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22,181,11,23,196,1, +2,54,23,197,1,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22,153, +7,23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11, +12,250,22,181,11,2,15,2,48,23,196,2,28,248,22,133,16,23,194,2,12, +251,22,183,11,2,15,2,53,2,46,23,197,1,86,95,86,94,86,94,28,28, +248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,133,16, +23,196,2,10,248,22,134,16,23,196,2,11,12,250,22,181,11,2,15,2,48, +23,198,2,28,248,22,133,16,23,196,2,12,251,22,183,11,2,15,2,53,2, 46,23,199,2,249,22,3,32,0,88,148,8,36,40,49,11,9,222,33,104,23, 198,2,28,28,248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22, -180,11,2,15,2,54,23,197,2,252,80,143,44,52,23,199,1,23,200,1,23, -201,1,11,11,86,94,28,28,248,22,173,15,23,194,2,10,28,248,22,153,7, -23,194,2,28,248,22,132,16,23,194,2,10,248,22,133,16,23,194,2,11,12, -250,22,180,11,2,17,2,48,23,196,2,28,248,22,132,16,23,194,2,12,251, -22,182,11,2,17,2,53,2,46,23,197,1,86,96,86,94,28,28,248,22,173, -15,23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,132,16,23,197,2, -10,248,22,133,16,23,197,2,11,12,250,22,180,11,2,17,2,48,23,199,2, -28,248,22,132,16,23,197,2,12,251,22,182,11,2,17,2,53,2,46,23,200, -2,86,94,86,94,28,28,248,22,173,15,23,198,2,10,28,248,22,153,7,23, -198,2,28,248,22,132,16,23,198,2,10,248,22,133,16,23,198,2,11,12,250, -22,180,11,2,17,2,48,23,200,2,28,248,22,132,16,23,198,2,12,251,22, -182,11,2,17,2,53,2,46,23,201,2,249,22,3,32,0,88,148,8,36,40, +181,11,2,15,2,54,23,197,2,252,80,143,44,52,23,199,1,23,200,1,23, +201,1,11,11,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22,153,7, +23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11,12, +250,22,181,11,2,17,2,48,23,196,2,28,248,22,133,16,23,194,2,12,251, +22,183,11,2,17,2,53,2,46,23,197,1,86,96,86,94,28,28,248,22,174, +15,23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,133,16,23,197,2, +10,248,22,134,16,23,197,2,11,12,250,22,181,11,2,17,2,48,23,199,2, +28,248,22,133,16,23,197,2,12,251,22,183,11,2,17,2,53,2,46,23,200, +2,86,94,86,94,28,28,248,22,174,15,23,198,2,10,28,248,22,153,7,23, +198,2,28,248,22,133,16,23,198,2,10,248,22,134,16,23,198,2,11,12,250, +22,181,11,2,17,2,48,23,200,2,28,248,22,133,16,23,198,2,12,251,22, +183,11,2,17,2,53,2,46,23,201,2,249,22,3,32,0,88,148,8,36,40, 49,11,9,222,33,106,23,200,2,28,28,248,22,0,23,195,2,249,22,48,23, -196,2,40,11,12,250,22,180,11,2,17,2,54,23,197,2,252,80,143,44,52, -23,199,1,23,202,1,23,203,1,23,201,1,23,200,1,27,248,22,150,16,2, -55,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248,22,133,16, -23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250, -80,144,49,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95, -23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23,196,1,27, -250,80,144,44,43,42,248,22,150,16,2,56,23,197,1,10,28,23,193,2,248, -22,137,16,23,194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42,27, -248,22,150,16,2,58,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1, -28,248,22,133,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16, -249,22,135,16,250,80,144,49,43,42,248,22,150,16,2,56,11,11,248,22,150, -16,2,57,86,95,23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199, -1,23,196,1,27,250,80,144,44,43,42,248,22,150,16,2,56,23,197,1,10, -28,23,193,2,248,22,137,16,23,194,1,11,249,80,144,41,55,40,40,80,144, +196,2,40,11,12,250,22,181,11,2,17,2,54,23,197,2,252,80,143,44,52, +23,199,1,23,202,1,23,203,1,23,201,1,23,200,1,27,248,22,151,16,2, +55,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16, +23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250, +80,144,49,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95, +23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27, +250,80,144,44,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248, +22,138,16,23,194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42,27, +248,22,151,16,2,58,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1, +28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16, +249,22,136,16,250,80,144,49,43,42,248,22,151,16,2,56,11,11,248,22,151, +16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199, +1,23,196,1,27,250,80,144,44,43,42,248,22,151,16,2,56,23,197,1,10, +28,23,193,2,248,22,138,16,23,194,1,11,249,80,144,41,55,40,40,80,144, 41,8,41,42,27,20,13,144,80,144,40,46,40,26,29,80,144,8,30,47,40, -249,22,31,11,80,144,8,32,46,40,22,143,15,10,22,144,15,10,22,145,15, -10,22,148,15,10,22,147,15,11,22,149,15,10,22,146,15,10,22,150,15,10, -22,151,15,10,22,152,15,10,22,153,15,10,22,154,15,11,22,155,15,10,22, -141,15,11,247,22,148,6,28,248,22,149,2,193,192,11,27,28,23,195,2,249, -22,191,15,23,197,1,6,11,11,99,111,110,102,105,103,46,114,107,116,100,86, -94,23,195,1,11,27,28,23,194,2,28,248,22,185,15,23,195,2,249,22,140, +249,22,31,11,80,144,8,32,46,40,22,144,15,10,22,145,15,10,22,146,15, +10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22,151,15,10, +22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156,15,10,22, +142,15,11,247,22,148,6,28,248,22,149,2,193,192,11,27,28,23,195,2,249, +22,128,16,23,197,1,6,11,11,99,111,110,102,105,103,46,114,107,116,100,86, +94,23,195,1,11,27,28,23,194,2,28,248,22,186,15,23,195,2,249,22,140, 6,23,196,1,80,144,43,8,42,42,11,11,28,192,192,21,17,1,0,250,22, 158,2,23,196,1,2,59,247,22,171,8,250,22,158,2,195,2,59,247,22,171, -8,28,248,22,153,7,23,195,2,27,248,22,181,15,23,196,1,28,248,22,134, -16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144,43,54,42,28,23, -193,2,192,86,94,23,193,1,247,22,151,16,28,248,22,142,8,23,195,2,27, -248,22,182,15,23,196,1,28,248,22,134,16,23,194,2,192,249,22,135,16,23, +8,28,248,22,153,7,23,195,2,27,248,22,182,15,23,196,1,28,248,22,135, +16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,43,54,42,28,23, +193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,142,8,23,195,2,27, +248,22,183,15,23,196,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23, 195,1,27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22, -151,16,28,248,22,173,15,23,195,2,28,248,22,134,16,23,195,2,193,249,22, -135,16,23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23,193, -1,247,22,151,16,193,27,248,22,150,16,2,55,28,248,22,134,16,23,194,2, -248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42,11,89,146, -42,39,11,248,22,130,16,249,22,135,16,250,80,144,49,43,42,248,22,150,16, -2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1,248,22,137, -16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,150, -16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1,11,28,248, -22,134,16,23,195,2,193,249,22,135,16,23,196,1,27,249,80,144,44,55,40, -39,80,144,44,8,43,42,28,23,193,2,192,86,94,23,193,1,247,22,151,16, -28,248,22,134,16,23,195,2,248,22,137,16,23,195,1,28,248,22,133,16,23, -195,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80, -144,48,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23, -195,1,23,194,1,248,22,137,16,249,22,135,16,23,200,1,23,196,1,27,250, -80,144,43,43,42,248,22,150,16,2,56,23,198,1,10,28,23,193,2,248,22, -137,16,23,194,1,11,28,248,22,88,23,196,2,9,28,248,22,81,23,196,2, -249,22,80,27,248,22,161,20,23,199,2,28,248,22,153,7,23,194,2,27,248, -22,181,15,23,195,1,28,248,22,134,16,23,194,2,192,249,22,135,16,23,195, -1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,151, -16,28,248,22,142,8,23,194,2,27,248,22,182,15,23,195,1,28,248,22,134, -16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144,46,54,42,28,23, -193,2,192,86,94,23,193,1,247,22,151,16,28,248,22,173,15,23,194,2,28, -248,22,134,16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144,45,54, -42,28,23,193,2,192,86,94,23,193,1,247,22,151,16,192,27,248,22,162,20, +152,16,28,248,22,174,15,23,195,2,28,248,22,135,16,23,195,2,193,249,22, +136,16,23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23,193, +1,247,22,152,16,193,27,248,22,151,16,2,55,28,248,22,135,16,23,194,2, +248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89,146, +42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22,151,16, +2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22,138, +16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,151, +16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28,248, +22,135,16,23,195,2,193,249,22,136,16,23,196,1,27,249,80,144,44,55,40, +39,80,144,44,8,43,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16, +28,248,22,135,16,23,195,2,248,22,138,16,23,195,1,28,248,22,134,16,23, +195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80, +144,48,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23, +195,1,23,194,1,248,22,138,16,249,22,136,16,23,200,1,23,196,1,27,250, +80,144,43,43,42,248,22,151,16,2,56,23,198,1,10,28,23,193,2,248,22, +138,16,23,194,1,11,28,248,22,88,23,196,2,9,28,248,22,81,23,196,2, +249,22,80,27,248,22,162,20,23,199,2,28,248,22,153,7,23,194,2,27,248, +22,182,15,23,195,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195, +1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152, +16,28,248,22,142,8,23,194,2,27,248,22,183,15,23,195,1,28,248,22,135, +16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,46,54,42,28,23, +193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,174,15,23,194,2,28, +248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,45,54, +42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,192,27,248,22,163,20, 23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80, -248,80,144,45,60,42,248,22,161,20,23,197,2,27,248,22,162,20,23,197,1, +248,80,144,45,60,42,248,22,162,20,23,197,2,27,248,22,163,20,23,197,1, 28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144, -48,60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, -22,162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, -1,248,22,162,20,23,198,1,249,22,94,23,199,2,27,248,22,162,20,23,197, +48,60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, +22,163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, +1,248,22,163,20,23,198,1,249,22,94,23,199,2,27,248,22,163,20,23,197, 1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80, -144,48,60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1, -248,22,162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, -204,1,248,22,162,20,23,198,1,249,22,94,23,196,2,27,248,22,162,20,23, +144,48,60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1, +248,22,163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, +204,1,248,22,163,20,23,198,1,249,22,94,23,196,2,27,248,22,163,20,23, 199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248, -80,144,45,60,42,248,22,161,20,23,197,2,27,248,22,162,20,23,197,1,28, +80,144,45,60,42,248,22,162,20,23,197,2,27,248,22,163,20,23,197,1,28, 248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144,48, -60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22, -162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1, -248,22,162,20,23,198,1,249,22,94,23,199,2,27,248,22,162,20,23,197,1, +60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22, +163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1, +248,22,163,20,23,198,1,249,22,94,23,199,2,27,248,22,163,20,23,197,1, 28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144, -48,60,42,248,22,161,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, -22,162,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, -1,248,22,162,20,23,198,1,27,250,22,158,2,23,198,1,23,199,1,11,28, -192,249,80,144,42,8,44,42,198,194,196,27,248,22,150,16,2,58,28,248,22, -134,16,23,194,2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90, -144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,49,43, -42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23, -194,1,248,22,137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,44, -43,42,248,22,150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23, +48,60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, +22,163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, +1,248,22,163,20,23,198,1,27,250,22,158,2,23,198,1,23,199,1,11,28, +192,249,80,144,42,8,44,42,198,194,196,27,248,22,151,16,2,58,28,248,22, +135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90, +144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43, +42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23, +194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44, +43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23, 194,1,11,27,248,80,144,41,58,42,249,80,144,43,55,40,40,80,144,43,8, 45,42,27,27,250,22,158,2,23,198,2,72,108,105,110,107,115,45,102,105,108, -101,11,27,28,23,194,2,23,194,1,86,94,23,194,1,249,22,191,15,27,250, +101,11,27,28,23,194,2,23,194,1,86,94,23,194,1,249,22,128,16,27,250, 22,158,2,23,202,2,71,115,104,97,114,101,45,100,105,114,11,28,192,192,249, -22,191,15,64,117,112,6,5,5,115,104,97,114,101,2,60,28,248,22,153,7, -23,194,2,27,248,22,181,15,23,195,1,28,248,22,134,16,23,194,2,192,249, -22,135,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23, -193,1,247,22,151,16,28,248,22,142,8,23,194,2,27,248,22,182,15,23,195, -1,28,248,22,134,16,23,194,2,192,249,22,135,16,23,195,1,27,247,80,144, -47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,151,16,28,248,22,173, -15,23,194,2,28,248,22,134,16,23,194,2,192,249,22,135,16,23,195,1,27, -247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,151,16,192, -250,22,94,248,22,90,11,28,247,22,158,16,28,247,22,159,16,248,22,90,250, -22,191,15,248,22,150,16,2,61,250,22,158,2,23,204,2,2,59,247,22,171, -8,2,60,9,9,28,247,22,159,16,250,80,144,47,8,23,42,23,200,1,1, +22,128,16,64,117,112,6,5,5,115,104,97,114,101,2,60,28,248,22,153,7, +23,194,2,27,248,22,182,15,23,195,1,28,248,22,135,16,23,194,2,192,249, +22,136,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23, +193,1,247,22,152,16,28,248,22,142,8,23,194,2,27,248,22,183,15,23,195, +1,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144, +47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,174, +15,23,194,2,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27, +247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,192, +250,22,94,248,22,90,11,28,247,22,159,16,28,247,22,160,16,248,22,90,250, +22,128,16,248,22,151,16,2,61,250,22,158,2,23,204,2,2,59,247,22,171, +8,2,60,9,9,28,247,22,160,16,250,80,144,47,8,23,42,23,200,1,1, 18,108,105,110,107,115,45,115,101,97,114,99,104,45,102,105,108,101,115,248,22, -90,23,200,1,9,248,22,172,13,23,194,1,249,22,14,80,144,41,8,26,41, -28,248,22,128,13,23,197,2,86,94,23,196,1,32,0,88,148,8,36,39,44, +90,23,200,1,9,248,22,173,13,23,194,1,249,22,14,80,144,41,8,26,41, +28,248,22,129,13,23,197,2,86,94,23,196,1,32,0,88,148,8,36,39,44, 11,9,222,11,20,20,94,88,148,8,36,39,46,11,9,223,3,33,124,23,196, 1,32,126,88,148,39,40,59,11,2,50,222,33,127,90,144,42,11,89,146,42, -39,11,248,22,130,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,173, -15,23,194,2,28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0, +39,11,248,22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174, +15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0, 88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22, -130,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2, -28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, -39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197, -1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186, +131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2, +28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, +39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197, +1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187, 15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9, -222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,1,86,95,23, -195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186,15,23,194,2, +222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95,23, +195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194,2, 249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248,2, 126,23,194,1,11,11,11,11,32,128,2,88,148,8,36,40,58,11,2,50,222, 33,129,2,27,249,22,163,6,8,128,128,23,196,2,28,248,22,148,7,23,194, @@ -488,150 +488,150 @@ 148,7,23,194,2,9,249,22,80,23,195,1,248,2,128,2,23,211,1,192,192, 248,22,133,6,23,194,1,20,13,144,80,144,40,8,28,40,80,144,40,8,46, 42,27,28,249,22,189,8,248,22,180,8,2,62,41,90,144,42,11,89,146,42, -39,11,248,22,130,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22,173, -15,23,194,2,28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0, +39,11,248,22,131,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22,174, +15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0, 88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22, -130,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2, -28,248,22,186,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, -39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197, -1,86,95,23,195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186, +131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2, +28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, +39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197, +1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187, 15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9, -222,11,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,1,86,95,23, -195,1,23,194,1,28,248,22,173,15,23,194,2,28,248,22,186,15,23,194,2, +222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95,23, +195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194,2, 249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248,2, -126,23,194,1,11,11,11,11,11,28,248,22,185,15,23,195,2,27,28,249,22, +126,23,194,1,11,11,11,11,11,28,248,22,186,15,23,195,2,27,28,249,22, 189,8,248,22,180,8,2,62,41,249,22,145,6,23,197,2,32,0,88,148,8, 36,39,44,11,9,222,11,11,86,94,28,23,194,2,248,22,147,6,23,195,1, 86,94,23,194,1,12,249,22,80,27,248,22,188,5,23,199,1,250,22,44,22, 35,88,148,39,39,8,24,11,9,223,3,33,130,2,20,20,94,88,148,8,36, 39,46,11,9,223,3,33,131,2,23,196,1,194,249,22,80,11,194,28,28,23, -195,2,28,248,22,82,23,196,2,248,22,167,9,249,22,174,14,39,248,22,162, +195,2,28,248,22,82,23,196,2,248,22,167,9,249,22,175,14,39,248,22,163, 20,23,199,2,11,11,194,86,94,23,195,1,249,22,12,20,20,94,88,148,8, 32,39,61,16,4,39,8,128,80,8,240,0,64,0,0,39,9,224,2,3,33, 132,2,23,196,1,80,144,41,8,26,41,27,248,22,167,9,194,28,192,192,248, -22,167,9,248,22,81,195,86,95,28,248,22,149,12,23,198,2,27,247,22,141, -12,28,249,22,131,12,23,195,2,2,63,251,22,137,12,23,197,1,2,63,250, +22,167,9,248,22,81,195,86,95,28,248,22,150,12,23,198,2,27,247,22,142, +12,28,249,22,132,12,23,195,2,2,63,251,22,138,12,23,197,1,2,63,250, 22,137,8,6,42,42,101,114,114,111,114,32,114,101,97,100,105,110,103,32,99, 111,108,108,101,99,116,105,111,110,32,108,105,110,107,115,32,102,105,108,101,32, -126,115,58,32,126,97,23,203,2,248,22,145,12,23,206,2,247,22,27,12,12, +126,115,58,32,126,97,23,203,2,248,22,146,12,23,206,2,247,22,27,12,12, 28,23,193,2,250,22,156,2,80,144,45,8,25,41,23,198,1,249,22,80,23, -198,1,21,17,0,0,86,95,23,195,1,23,193,1,12,28,248,22,149,12,23, +198,1,21,17,0,0,86,95,23,195,1,23,193,1,12,28,248,22,150,12,23, 198,2,86,94,23,197,1,248,23,195,1,247,22,138,2,196,88,148,39,40,58, 8,240,0,0,0,2,9,226,0,2,1,3,33,135,2,20,20,94,248,22,148, -6,23,194,2,28,248,22,148,7,248,22,148,6,23,195,1,12,248,22,176,11, +6,23,194,2,28,248,22,148,7,248,22,148,6,23,195,1,12,248,22,177,11, 6,30,30,101,120,112,101,99,116,101,100,32,97,32,115,105,110,103,108,101,32, 83,45,101,120,112,114,101,115,115,105,111,110,248,22,133,6,23,194,1,28,248, 22,89,193,28,28,249,22,128,4,41,248,22,93,195,10,249,22,128,4,42,248, 22,93,195,28,28,248,22,153,7,248,22,81,194,10,28,249,22,169,9,2,64, -248,22,161,20,195,10,249,22,169,9,2,65,248,22,161,20,195,28,27,248,22, -102,194,28,248,22,173,15,193,10,28,248,22,153,7,193,28,248,22,132,16,193, -10,248,22,133,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22,179, -16,248,22,111,195,11,11,11,11,28,248,22,186,15,249,22,191,15,23,196,2, -23,198,2,27,248,22,68,248,22,177,15,23,198,1,250,22,156,2,23,198,2, +248,22,162,20,195,10,249,22,169,9,2,65,248,22,162,20,195,28,27,248,22, +102,194,28,248,22,174,15,193,10,28,248,22,153,7,193,28,248,22,133,16,193, +10,248,22,134,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22,180, +16,248,22,111,195,11,11,11,11,28,248,22,187,15,249,22,128,16,23,196,2, +23,198,2,27,248,22,68,248,22,178,15,23,198,1,250,22,156,2,23,198,2, 23,196,2,249,22,80,23,199,1,250,22,158,2,23,203,1,23,201,1,9,12, 250,22,156,2,23,197,1,23,198,1,249,22,80,23,198,1,23,201,1,28,28, -248,22,88,248,22,104,23,197,2,10,249,22,170,16,248,22,111,23,198,2,247, -22,171,8,27,248,22,137,16,249,22,135,16,248,22,102,23,200,2,23,198,1, -28,249,22,169,9,248,22,161,20,23,199,2,2,65,86,94,23,196,1,249,22, +248,22,88,248,22,104,23,197,2,10,249,22,171,16,248,22,111,23,198,2,247, +22,171,8,27,248,22,138,16,249,22,136,16,248,22,102,23,200,2,23,198,1, +28,249,22,169,9,248,22,162,20,23,199,2,2,65,86,94,23,196,1,249,22, 3,20,20,94,88,148,8,36,40,56,11,9,224,3,2,33,140,2,23,196,1, -248,22,140,16,23,196,1,28,249,22,169,9,248,22,161,20,23,199,2,2,64, +248,22,141,16,23,196,1,28,249,22,169,9,248,22,162,20,23,199,2,2,64, 86,94,23,196,1,86,94,28,250,22,158,2,23,197,2,11,11,12,250,22,156, 2,23,197,2,11,9,249,22,164,2,23,196,2,20,20,95,88,148,8,36,41, 53,11,9,224,3,2,33,141,2,23,195,1,23,196,1,27,248,22,68,248,22, -161,20,23,199,1,250,22,156,2,23,198,2,23,196,2,249,22,80,248,22,129, +162,20,23,199,1,250,22,156,2,23,198,2,23,196,2,249,22,80,248,22,129, 2,23,200,1,250,22,158,2,23,203,1,23,201,1,9,12,250,22,156,2,23, 196,1,23,197,1,248,22,95,23,199,1,27,28,28,23,194,2,248,22,167,9, 248,22,81,23,196,2,10,9,27,249,22,188,5,23,198,2,68,98,105,110,97, 114,121,250,22,44,22,35,88,148,8,36,39,47,11,9,223,3,33,137,2,20, 20,94,88,148,8,36,39,46,11,9,223,3,33,138,2,23,196,1,86,94,28, 28,248,22,89,23,194,2,249,22,4,32,0,88,148,8,36,40,48,11,9,222, -33,139,2,23,195,2,11,12,248,22,176,11,6,18,18,105,108,108,45,102,111, +33,139,2,23,195,2,11,12,248,22,177,11,6,18,18,105,108,108,45,102,111, 114,109,101,100,32,99,111,110,116,101,110,116,27,247,22,138,2,27,90,144,42, -11,89,146,42,39,11,248,22,130,16,23,201,2,192,86,96,249,22,3,20,20, +11,89,146,42,39,11,248,22,131,16,23,201,2,192,86,96,249,22,3,20,20, 94,88,148,8,36,40,57,11,9,224,2,3,33,142,2,23,195,1,23,197,1, 249,22,164,2,195,88,148,8,36,41,51,11,9,223,3,33,143,2,250,22,156, 2,80,144,47,8,25,41,23,200,1,249,22,80,23,201,1,198,193,20,13,144, 80,144,40,8,28,40,250,80,144,43,8,47,42,23,198,2,23,196,2,11,27, 250,22,158,2,80,144,44,8,25,41,23,197,2,21,143,11,17,0,0,27,248, 22,81,23,195,2,27,249,80,144,45,8,27,42,23,198,2,23,196,2,28,249, -22,171,9,23,195,2,23,196,1,248,22,162,20,195,86,94,23,195,1,20,13, +22,171,9,23,195,2,23,196,1,248,22,163,20,195,86,94,23,195,1,20,13, 144,80,144,43,8,28,40,250,80,144,46,8,47,42,23,201,1,23,199,2,23, 196,2,27,20,20,95,88,148,8,36,39,55,8,240,0,0,0,2,9,225,5, 4,1,33,144,2,23,194,1,23,197,1,28,249,22,48,23,195,2,39,20,13, 144,80,144,44,46,40,26,29,80,144,8,34,47,40,249,22,31,11,80,144,8, -36,46,40,22,143,15,10,22,144,15,10,22,145,15,10,22,148,15,10,22,147, -15,11,22,149,15,10,22,146,15,10,22,150,15,10,22,151,15,10,22,152,15, -10,22,153,15,10,22,154,15,11,22,155,15,10,22,141,15,11,247,23,193,1, -250,22,180,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39,40, +36,46,40,22,144,15,10,22,145,15,10,22,146,15,10,22,149,15,10,22,148, +15,11,22,150,15,10,22,147,15,10,22,151,15,10,22,152,15,10,22,153,15, +10,22,154,15,10,22,155,15,11,22,156,15,10,22,142,15,11,247,23,193,1, +250,22,181,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39,40, 8,43,16,4,8,128,6,8,128,104,8,240,0,128,0,0,39,9,224,1,2, 33,145,2,23,195,1,0,7,35,114,120,34,47,43,34,28,248,22,153,7,23, -195,2,27,249,22,168,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128, +195,2,27,249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128, 4,248,22,101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7, 250,22,175,7,23,200,1,39,248,22,101,23,199,1,23,198,1,249,22,7,250, 22,175,7,23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23, 201,1,248,22,103,23,200,1,23,200,1,249,22,7,23,197,1,23,198,1,90, -144,42,11,89,146,42,39,11,248,22,130,16,23,198,1,86,94,23,195,1,28, +144,42,11,89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1,28, 249,22,169,9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23, 200,1,27,249,22,80,23,197,1,23,201,1,28,248,22,153,7,23,195,2,27, -249,22,168,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128,4,248,22, +249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128,4,248,22, 101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7,250,22,175, 7,23,200,1,39,248,22,101,23,199,1,23,196,1,249,22,7,250,22,175,7, 23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23,201,1,248, 22,103,23,200,1,23,198,1,249,22,7,23,197,1,23,196,1,90,144,42,11, -89,146,42,39,11,248,22,130,16,23,198,1,86,94,23,195,1,28,249,22,169, +89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1,28,249,22,169, 9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23,198,1,249, 80,144,48,8,31,42,194,249,22,80,197,199,28,248,22,88,23,196,2,9,28, -248,22,81,23,196,2,28,248,22,149,2,248,22,161,20,23,197,2,250,22,94, -249,22,2,22,129,2,250,22,158,2,248,22,161,20,23,204,2,23,202,2,9, -250,22,158,2,248,22,161,20,23,202,2,11,9,27,248,22,162,20,23,200,1, +248,22,81,23,196,2,28,248,22,149,2,248,22,162,20,23,197,2,250,22,94, +249,22,2,22,129,2,250,22,158,2,248,22,162,20,23,204,2,23,202,2,9, +250,22,158,2,248,22,162,20,23,202,2,11,9,27,248,22,163,20,23,200,1, 28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248, -22,161,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22, -161,20,23,202,2,23,206,2,9,250,22,158,2,248,22,161,20,23,200,2,11, -9,249,80,144,48,8,48,42,23,203,1,248,22,162,20,23,199,1,27,248,80, -144,45,8,30,42,248,22,161,20,23,196,2,250,22,94,250,22,158,2,23,199, +22,162,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22, +162,20,23,202,2,23,206,2,9,250,22,158,2,248,22,162,20,23,200,2,11, +9,249,80,144,48,8,48,42,23,203,1,248,22,163,20,23,199,1,27,248,80, +144,45,8,30,42,248,22,162,20,23,196,2,250,22,94,250,22,158,2,23,199, 2,23,205,2,9,250,22,158,2,23,199,1,11,9,249,80,144,49,8,48,42, -23,204,1,248,22,162,20,23,200,1,249,22,94,247,22,154,16,249,80,144,47, -8,48,42,23,202,1,248,22,162,20,23,198,1,27,248,80,144,41,8,30,42, -248,22,161,20,23,198,2,250,22,94,250,22,158,2,23,199,2,23,201,2,9, -250,22,158,2,23,199,1,11,9,27,248,22,162,20,23,201,1,28,248,22,88, -23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,161,20,23, -195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,161,20,23,202, -2,23,207,2,9,250,22,158,2,248,22,161,20,23,200,2,11,9,249,80,144, -49,8,48,42,23,204,1,248,22,162,20,23,199,1,27,248,80,144,46,8,30, -42,248,22,161,20,23,196,2,250,22,94,250,22,158,2,23,199,2,23,206,2, +23,204,1,248,22,163,20,23,200,1,249,22,94,247,22,155,16,249,80,144,47, +8,48,42,23,202,1,248,22,163,20,23,198,1,27,248,80,144,41,8,30,42, +248,22,162,20,23,198,2,250,22,94,250,22,158,2,23,199,2,23,201,2,9, +250,22,158,2,23,199,1,11,9,27,248,22,163,20,23,201,1,28,248,22,88, +23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,162,20,23, +195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,162,20,23,202, +2,23,207,2,9,250,22,158,2,248,22,162,20,23,200,2,11,9,249,80,144, +49,8,48,42,23,204,1,248,22,163,20,23,199,1,27,248,80,144,46,8,30, +42,248,22,162,20,23,196,2,250,22,94,250,22,158,2,23,199,2,23,206,2, 9,250,22,158,2,23,199,1,11,9,249,80,144,50,8,48,42,23,205,1,248, -22,162,20,23,200,1,249,22,94,247,22,154,16,249,80,144,48,8,48,42,23, -203,1,248,22,162,20,23,198,1,249,22,94,247,22,154,16,27,248,22,162,20, +22,163,20,23,200,1,249,22,94,247,22,155,16,249,80,144,48,8,48,42,23, +203,1,248,22,163,20,23,198,1,249,22,94,247,22,155,16,27,248,22,163,20, 23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22, -149,2,248,22,161,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158, -2,248,22,161,20,23,202,2,23,205,2,9,250,22,158,2,248,22,161,20,23, -200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,162,20,23,199,1, -27,248,80,144,44,8,30,42,248,22,161,20,23,196,2,250,22,94,250,22,158, +149,2,248,22,162,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158, +2,248,22,162,20,23,202,2,23,205,2,9,250,22,158,2,248,22,162,20,23, +200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,163,20,23,199,1, +27,248,80,144,44,8,30,42,248,22,162,20,23,196,2,250,22,94,250,22,158, 2,23,199,2,23,204,2,9,250,22,158,2,23,199,1,11,9,249,80,144,48, -8,48,42,23,203,1,248,22,162,20,23,200,1,249,22,94,247,22,154,16,249, -80,144,46,8,48,42,23,201,1,248,22,162,20,23,198,1,32,150,2,88,148, +8,48,42,23,203,1,248,22,163,20,23,200,1,249,22,94,247,22,155,16,249, +80,144,46,8,48,42,23,201,1,248,22,163,20,23,198,1,32,150,2,88,148, 8,36,40,50,11,2,50,222,33,151,2,28,248,22,88,248,22,82,23,195,2, -248,22,90,27,248,22,161,20,195,28,248,22,173,15,193,248,22,177,15,193,192, -250,22,91,27,248,22,161,20,23,198,2,28,248,22,173,15,193,248,22,177,15, -193,192,2,67,248,2,150,2,248,22,162,20,23,198,1,250,22,137,8,6,7, +248,22,90,27,248,22,162,20,195,28,248,22,174,15,193,248,22,178,15,193,192, +250,22,91,27,248,22,162,20,23,198,2,28,248,22,174,15,193,248,22,178,15, +193,192,2,67,248,2,150,2,248,22,163,20,23,198,1,250,22,137,8,6,7, 7,10,32,126,97,32,126,97,6,1,1,32,23,196,1,249,22,137,8,6,6, 6,10,32,32,32,126,97,248,22,132,2,23,196,1,32,154,2,88,148,39,41, 51,11,68,102,105,108,116,101,114,222,33,155,2,28,248,22,88,23,195,2,9, -28,248,23,194,2,248,22,81,23,196,2,249,22,80,248,22,161,20,23,197,2, -249,2,154,2,23,197,1,248,22,162,20,23,199,1,249,2,154,2,23,195,1, -248,22,162,20,23,197,1,28,248,22,88,23,201,2,86,95,23,200,1,23,199, -1,28,23,201,2,28,197,249,22,191,15,202,199,200,27,28,248,22,88,23,198, +28,248,23,194,2,248,22,81,23,196,2,249,22,80,248,22,162,20,23,197,2, +249,2,154,2,23,197,1,248,22,163,20,23,199,1,249,2,154,2,23,195,1, +248,22,163,20,23,197,1,28,248,22,88,23,201,2,86,95,23,200,1,23,199, +1,28,23,201,2,28,197,249,22,128,16,202,199,200,27,28,248,22,88,23,198, 2,2,66,249,22,1,22,176,7,248,2,150,2,23,200,2,248,23,199,1,251, 22,137,8,6,70,70,99,111,108,108,101,99,116,105,111,110,32,110,111,116,32, 102,111,117,110,100,10,32,32,99,111,108,108,101,99,116,105,111,110,58,32,126, 115,10,32,32,105,110,32,99,111,108,108,101,99,116,105,111,110,32,100,105,114, 101,99,116,111,114,105,101,115,58,126,97,126,97,28,248,22,88,23,203,1,28, -248,22,173,15,23,202,2,248,22,177,15,23,202,1,23,201,1,250,22,176,7, -28,248,22,173,15,23,205,2,248,22,177,15,23,205,1,23,204,1,2,67,23, +248,22,174,15,23,202,2,248,22,178,15,23,202,1,23,201,1,250,22,176,7, +28,248,22,174,15,23,205,2,248,22,178,15,23,205,1,23,204,1,2,67,23, 201,2,249,22,1,22,176,7,249,22,2,32,0,88,148,8,36,40,48,11,9, -222,33,152,2,27,248,22,93,23,206,2,27,248,22,93,247,22,154,16,28,249, +222,33,152,2,27,248,22,93,23,206,2,27,248,22,93,247,22,155,16,28,249, 22,129,4,249,22,184,3,23,198,2,23,197,2,44,23,206,2,249,22,94,247, -22,154,16,248,22,90,249,22,137,8,6,50,50,46,46,46,32,91,126,97,32, +22,155,16,248,22,90,249,22,137,8,6,50,50,46,46,46,32,91,126,97,32, 97,100,100,105,116,105,111,110,97,108,32,108,105,110,107,101,100,32,97,110,100, 32,112,97,99,107,97,103,101,32,100,105,114,101,99,116,111,114,105,101,115,93, 249,22,184,3,23,201,1,23,200,1,28,249,22,5,22,131,2,23,202,2,250, @@ -640,311 +640,311 @@ 105,114,101,99,116,111,114,105,101,115,58,126,97,23,201,1,249,22,1,22,176, 7,249,22,2,32,0,88,148,8,36,40,48,11,9,222,33,153,2,249,2,154, 2,22,131,2,23,209,1,86,95,23,200,1,23,198,1,2,66,27,248,22,81, -23,202,2,27,28,248,22,173,15,23,195,2,249,22,191,15,23,196,1,23,199, -2,248,22,132,2,23,195,1,28,28,248,22,173,15,248,22,161,20,23,204,2, -248,22,186,15,23,194,2,10,27,250,22,1,22,191,15,23,197,1,23,202,2, -28,28,248,22,88,23,200,2,10,248,22,186,15,23,194,2,28,23,201,2,28, -28,250,80,144,45,8,32,42,195,203,204,10,27,28,248,22,173,15,202,248,22, -177,15,202,201,19,248,22,156,7,23,195,2,27,28,249,22,132,4,23,196,4, +23,202,2,27,28,248,22,174,15,23,195,2,249,22,128,16,23,196,1,23,199, +2,248,22,132,2,23,195,1,28,28,248,22,174,15,248,22,162,20,23,204,2, +248,22,187,15,23,194,2,10,27,250,22,1,22,128,16,23,197,1,23,202,2, +28,28,248,22,88,23,200,2,10,248,22,187,15,23,194,2,28,23,201,2,28, +28,250,80,144,45,8,32,42,195,203,204,10,27,28,248,22,174,15,202,248,22, +178,15,202,201,19,248,22,156,7,23,195,2,27,28,249,22,132,4,23,196,4, 43,28,249,22,159,7,6,4,4,46,114,107,116,249,22,175,7,23,199,2,249, 22,184,3,23,200,4,43,249,22,176,7,250,22,175,7,23,200,1,39,249,22, 184,3,23,201,4,43,6,3,3,46,115,115,86,94,23,195,1,11,11,28,23, 193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249,22, -191,15,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16,23, -17,248,22,162,20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8,49, -42,204,205,206,23,15,23,16,23,17,248,22,162,20,23,19,23,19,26,8,80, -144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,162,20,23,18,23,18, +128,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16,23, +17,248,22,163,20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8,49, +42,204,205,206,23,15,23,16,23,17,248,22,163,20,23,19,23,19,26,8,80, +144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,163,20,23,18,23,18, 90,144,41,11,89,146,41,39,11,249,80,144,43,8,31,42,23,199,1,23,200, -1,27,248,22,68,28,248,22,173,15,195,248,22,177,15,195,194,27,27,247,22, -155,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149, -2,248,22,161,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, -248,22,161,20,23,202,2,23,203,2,9,250,22,158,2,248,22,161,20,23,200, -2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,162,20,23,199,1,27, -248,80,144,46,8,30,42,248,22,161,20,23,196,2,250,22,94,250,22,158,2, +1,27,248,22,68,28,248,22,174,15,195,248,22,178,15,195,194,27,27,247,22, +156,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149, +2,248,22,162,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, +248,22,162,20,23,202,2,23,203,2,9,250,22,158,2,248,22,162,20,23,200, +2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,163,20,23,199,1,27, +248,80,144,46,8,30,42,248,22,162,20,23,196,2,250,22,94,250,22,158,2, 23,199,2,23,202,2,9,250,22,158,2,23,199,1,11,9,249,80,144,50,8, -48,42,23,201,1,248,22,162,20,23,200,1,249,22,94,247,22,154,16,249,80, -144,48,8,48,42,23,199,1,248,22,162,20,23,198,1,26,8,80,144,51,8, +48,42,23,201,1,248,22,163,20,23,200,1,249,22,94,247,22,155,16,249,80, +144,48,8,48,42,23,199,1,248,22,163,20,23,198,1,26,8,80,144,51,8, 49,42,200,202,203,205,23,16,23,17,200,11,32,158,2,88,148,8,36,42,59, 11,2,50,222,33,159,2,28,248,22,133,4,23,196,2,86,94,23,195,1,19, -248,22,147,8,23,195,2,19,248,22,147,8,23,196,2,249,22,183,15,27,251, +248,22,147,8,23,195,2,19,248,22,147,8,23,196,2,249,22,184,15,27,251, 22,154,8,250,22,153,8,23,205,2,39,23,204,4,2,51,249,22,153,8,23, 204,1,23,202,4,2,68,28,248,22,133,4,248,22,147,8,23,195,2,86,94, -23,193,1,251,22,182,11,2,37,2,69,2,70,202,192,28,248,22,174,15,198, -248,22,175,15,198,247,22,176,15,2,2,27,248,22,182,3,23,197,1,28,249, +23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248,22,175,15,198, +248,22,176,15,198,247,22,177,15,2,2,27,248,22,182,3,23,197,1,28,249, 22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248,22,181,3,23, -195,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204, +195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204, 1,2,71,249,22,153,8,23,204,1,23,202,1,2,68,28,248,22,133,4,248, -22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70, -202,192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15,250,2,158,2, -196,197,195,248,22,185,15,27,250,22,191,15,23,200,1,23,202,1,23,199,1, -28,249,22,169,9,23,197,2,66,115,97,109,101,192,28,248,22,132,16,23,196, -2,249,22,191,15,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249,22, +22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, +202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,250,2,158,2, +196,197,195,248,22,186,15,27,250,22,128,16,23,200,1,23,202,1,23,199,1, +28,249,22,169,9,23,197,2,66,115,97,109,101,192,28,248,22,133,16,23,196, +2,249,22,128,16,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249,22, 5,20,20,96,88,148,39,40,54,47,9,226,5,4,2,6,33,160,2,23,199, -1,23,195,1,23,197,1,23,196,1,27,248,22,185,15,249,22,191,15,23,198, +1,23,195,1,23,197,1,23,196,1,27,248,22,186,15,249,22,128,16,23,198, 2,23,199,2,28,23,193,2,192,86,94,23,193,1,28,23,197,1,27,90,144, 41,11,89,146,41,39,11,250,80,144,46,8,34,42,23,202,2,2,68,2,37, -27,248,22,179,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248,22, -147,8,23,198,1,28,248,22,174,15,195,249,22,191,15,196,194,192,27,247,22, -156,16,249,22,5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3,33, -161,2,23,196,1,23,195,1,23,199,1,247,22,157,16,11,86,95,28,28,248, -22,174,15,23,194,2,10,28,248,22,173,15,23,194,2,10,28,248,22,153,7, -23,194,2,28,248,22,132,16,23,194,2,10,248,22,133,16,23,194,2,11,12, -252,22,180,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22,153, -7,23,195,2,10,248,22,142,8,23,195,2,86,94,23,194,1,12,252,22,180, +27,248,22,180,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248,22, +147,8,23,198,1,28,248,22,175,15,195,249,22,128,16,196,194,192,27,247,22, +157,16,249,22,5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3,33, +161,2,23,196,1,23,195,1,23,199,1,247,22,158,16,11,86,95,28,28,248, +22,175,15,23,194,2,10,28,248,22,174,15,23,194,2,10,28,248,22,153,7, +23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11,12, +252,22,181,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22,153, +7,23,195,2,10,248,22,142,8,23,195,2,86,94,23,194,1,12,252,22,181, 11,23,200,2,2,72,40,23,198,2,23,199,1,90,144,42,11,89,146,42,39, -11,248,22,130,16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86,95, -23,198,1,23,196,1,12,250,22,183,11,23,201,1,2,73,23,199,1,249,22, +11,248,22,131,16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86,95, +23,198,1,23,196,1,12,250,22,184,11,23,201,1,2,73,23,199,1,249,22, 7,23,195,1,23,196,1,32,164,2,88,148,8,36,46,61,11,2,74,222,33, -165,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,203,2,39,23,207, +165,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2,39,23,207, 1,23,205,1,249,23,203,1,23,202,1,23,208,1,28,248,22,153,7,23,204, 2,249,22,168,8,23,205,1,8,63,23,203,1,28,248,22,133,4,248,22,147, -8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,201,192, -28,248,22,174,15,197,248,22,175,15,197,247,22,176,15,32,166,2,88,148,8, +8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,201,192, +28,248,22,175,15,197,248,22,176,15,197,247,22,177,15,32,166,2,88,148,8, 36,45,8,24,11,2,50,222,33,167,2,28,248,22,133,4,23,199,2,86,95, 23,198,1,23,194,1,19,248,22,147,8,23,195,2,19,248,22,147,8,23,196, -2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204,4, +2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204,4, 2,51,249,23,206,1,23,204,1,23,202,4,28,248,22,153,7,23,207,2,249, 22,168,8,23,208,1,8,63,23,206,1,28,248,22,133,4,248,22,147,8,23, -195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,204,192,28,248, -22,174,15,200,248,22,175,15,200,247,22,176,15,2,2,27,248,22,182,3,23, +195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,204,192,28,248, +22,175,15,200,248,22,176,15,200,247,22,177,15,2,2,27,248,22,182,3,23, 200,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248, -22,181,3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205, +22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205, 2,39,23,204,1,23,203,1,249,23,206,1,23,204,1,23,202,1,28,248,22, 153,7,23,207,2,249,22,168,8,23,208,1,8,63,23,206,1,28,248,22,133, -4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69, -2,70,204,192,28,248,22,174,15,200,248,22,175,15,200,247,22,176,15,28,248, +4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69, +2,70,204,192,28,248,22,175,15,200,248,22,176,15,200,247,22,177,15,28,248, 22,133,4,23,194,2,86,95,23,195,1,23,193,1,19,248,22,147,8,23,196, -2,19,248,22,147,8,23,197,2,249,22,183,15,27,251,22,154,8,250,22,153, +2,19,248,22,147,8,23,197,2,249,22,184,15,27,251,22,154,8,250,22,153, 8,23,206,2,39,23,204,4,2,51,249,23,207,1,23,205,1,23,202,4,28, 248,22,153,7,23,208,2,249,22,168,8,23,209,1,8,63,23,207,1,28,248, -22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37, -2,69,2,70,205,192,28,248,22,174,15,201,248,22,175,15,201,247,22,176,15, +22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37, +2,69,2,70,205,192,28,248,22,175,15,201,248,22,176,15,201,247,22,177,15, 2,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148,8, -23,199,2,23,197,2,27,248,22,181,3,23,195,2,249,22,183,15,27,251,22, +23,199,2,23,197,2,27,248,22,181,3,23,195,2,249,22,184,15,27,251,22, 154,8,250,22,153,8,23,206,2,39,23,204,1,23,204,1,249,23,207,1,23, 205,1,23,202,1,28,248,22,153,7,23,208,2,249,22,168,8,23,209,1,8, 63,23,207,1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1, -251,22,182,11,2,37,2,69,2,70,205,192,28,248,22,174,15,201,248,22,175, -15,201,247,22,176,15,28,248,22,133,4,193,254,2,164,2,201,203,204,205,248, +251,22,183,11,2,37,2,69,2,70,205,192,28,248,22,175,15,201,248,22,176, +15,201,247,22,177,15,28,248,22,133,4,193,254,2,164,2,201,203,204,205,248, 22,147,8,202,2,51,248,22,147,8,202,27,248,22,182,3,194,28,249,22,169, 9,8,46,249,22,148,8,199,196,254,2,164,2,202,204,205,206,199,203,248,22, 181,3,200,253,2,166,2,201,202,203,204,205,198,90,144,41,11,89,146,41,39, -11,86,95,28,28,248,22,174,15,23,199,2,10,28,248,22,173,15,23,199,2, -10,28,248,22,153,7,23,199,2,28,248,22,132,16,23,199,2,10,248,22,133, -16,23,199,2,11,12,252,22,180,11,23,200,2,2,42,39,23,203,2,23,204, +11,86,95,28,28,248,22,175,15,23,199,2,10,28,248,22,174,15,23,199,2, +10,28,248,22,153,7,23,199,2,28,248,22,133,16,23,199,2,10,248,22,134, +16,23,199,2,11,12,252,22,181,11,23,200,2,2,42,39,23,203,2,23,204, 2,28,28,248,22,153,7,23,200,2,10,248,22,142,8,23,200,2,12,252,22, -180,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146,42, -39,11,248,22,130,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250,22, -183,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,179,15,23, +181,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146,42, +39,11,248,22,131,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250,22, +184,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,180,15,23, 196,1,27,19,248,22,147,8,23,196,2,28,248,22,133,4,23,194,4,86,94, 23,199,1,19,248,22,147,8,23,197,2,19,248,22,147,8,23,198,2,249,22, -183,15,27,251,22,154,8,250,22,153,8,23,207,2,39,23,204,4,2,51,249, +184,15,27,251,22,154,8,250,22,153,8,23,207,2,39,23,204,4,2,51,249, 23,211,1,23,206,1,23,202,4,28,248,22,153,7,23,212,2,249,22,168,8, 23,213,1,8,63,23,211,1,28,248,22,133,4,248,22,147,8,23,195,2,86, -94,23,193,1,251,22,182,11,2,37,2,69,2,70,23,17,192,28,248,22,174, -15,205,248,22,175,15,205,247,22,176,15,2,2,27,248,22,182,3,23,195,4, +94,23,193,1,251,22,183,11,2,37,2,69,2,70,23,17,192,28,248,22,175, +15,205,248,22,176,15,205,247,22,177,15,2,2,27,248,22,182,3,23,195,4, 28,249,22,169,9,8,46,249,22,148,8,23,200,2,23,197,2,27,248,22,181, -3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,207,2,39, +3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,207,2,39, 23,204,1,23,208,1,249,23,211,1,23,206,1,23,202,1,28,248,22,153,7, 23,212,2,249,22,168,8,23,213,1,8,63,23,211,1,28,248,22,133,4,248, -22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70, -23,17,192,28,248,22,174,15,205,248,22,175,15,205,247,22,176,15,28,248,22, +22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, +23,17,192,28,248,22,175,15,205,248,22,176,15,205,247,22,177,15,28,248,22, 133,4,23,194,2,86,95,23,200,1,23,193,1,254,2,164,2,23,203,2,23, 208,1,23,209,1,23,210,1,248,22,147,8,23,204,2,2,51,248,22,147,8, 23,204,1,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148, 8,23,201,2,23,197,2,254,2,164,2,23,204,1,23,209,1,23,210,1,23, 211,1,23,200,2,23,208,1,248,22,181,3,23,201,1,253,2,166,2,23,203, -1,23,207,1,23,208,1,23,209,1,23,210,1,23,199,1,2,28,248,22,174, -15,195,249,22,191,15,196,194,192,32,169,2,88,148,8,36,43,61,11,2,50, +1,23,207,1,23,208,1,23,209,1,23,210,1,23,199,1,2,28,248,22,175, +15,195,249,22,128,16,196,194,192,32,169,2,88,148,8,36,43,61,11,2,50, 222,33,170,2,28,248,22,133,4,23,197,2,86,94,23,196,1,19,248,22,147, -8,23,195,2,35,248,22,147,8,23,196,2,249,22,183,15,27,251,22,154,8, +8,23,195,2,35,248,22,147,8,23,196,2,249,22,184,15,27,251,22,154,8, 250,22,153,8,23,205,1,39,23,204,4,2,51,2,51,28,248,22,153,7,23, 205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22, -147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,202, -192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15,2,27,248,22,182, +147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202, +192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,27,248,22,182, 3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2, -35,248,22,181,3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153,8, +35,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8, 23,205,1,39,23,204,1,2,51,2,51,28,248,22,153,7,23,205,2,249,22, 168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22,147,8,23,195, -2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,202,192,28,248,22, -174,15,198,248,22,175,15,198,247,22,176,15,28,248,22,133,4,23,194,2,86, +2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248,22, +175,15,198,248,22,176,15,198,247,22,177,15,28,248,22,133,4,23,194,2,86, 94,23,193,1,19,248,22,147,8,23,196,2,35,248,22,147,8,23,197,2,249, -22,183,15,27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,4,2,51, +22,184,15,27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,4,2,51, 2,51,28,248,22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205, -1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182, -11,2,37,2,69,2,70,203,192,28,248,22,174,15,199,248,22,175,15,199,247, -22,176,15,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22, -148,8,23,199,2,23,197,2,35,248,22,181,3,23,195,2,249,22,183,15,27, +1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183, +11,2,37,2,69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199,247, +22,177,15,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22, +148,8,23,199,2,23,197,2,35,248,22,181,3,23,195,2,249,22,184,15,27, 251,22,154,8,250,22,153,8,23,206,1,39,23,204,1,2,51,2,51,28,248, 22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205,1,28,248,22, -133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2, -69,2,70,203,192,28,248,22,174,15,199,248,22,175,15,199,247,22,176,15,251, +133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2, +69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199,247,22,177,15,251, 2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248, -22,174,15,23,196,2,10,28,248,22,173,15,23,196,2,10,28,248,22,153,7, -23,196,2,28,248,22,132,16,23,196,2,10,248,22,133,16,23,196,2,11,12, -252,22,180,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7, -23,197,2,10,248,22,142,8,23,197,2,12,252,22,180,11,2,37,2,72,40, -23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,199, -2,86,94,23,195,1,86,94,28,192,12,250,22,183,11,2,37,2,73,23,201, -2,249,22,7,194,195,27,248,22,179,15,23,196,1,27,251,2,169,2,23,198, -2,23,201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,174,15,195,249, -22,191,15,196,194,192,2,51,252,80,144,44,8,35,42,2,37,2,51,32,0, +22,175,15,23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153,7, +23,196,2,28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,12, +252,22,181,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7, +23,197,2,10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72,40, +23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,199, +2,86,94,23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23,201, +2,249,22,7,194,195,27,248,22,180,15,23,196,1,27,251,2,169,2,23,198, +2,23,201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195,249, +22,128,16,196,194,192,2,51,252,80,144,44,8,35,42,2,37,2,51,32,0, 88,148,8,36,41,46,11,9,222,33,172,2,198,199,32,174,2,88,148,8,36, 43,60,11,2,50,222,33,177,2,32,175,2,88,148,8,36,45,60,11,2,74, -222,33,176,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,203,2,39, +222,33,176,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2,39, 23,206,1,23,204,1,249,22,153,8,23,202,1,23,207,1,28,248,22,153,7, 23,203,2,249,22,168,8,23,204,1,8,63,23,202,1,28,248,22,133,4,248, -22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70, -200,192,28,248,22,174,15,196,248,22,175,15,196,247,22,176,15,28,248,22,133, +22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, +200,192,28,248,22,175,15,196,248,22,176,15,196,247,22,177,15,28,248,22,133, 4,23,197,2,86,94,23,196,1,19,248,22,147,8,23,195,2,19,248,22,147, -8,23,196,2,249,22,183,15,27,251,22,154,8,250,22,153,8,23,205,2,39, +8,23,196,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39, 23,204,4,2,51,249,22,153,8,23,204,1,23,202,4,28,248,22,153,7,23, 205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22, -147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37,2,69,2,70,202, -192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15,2,2,27,248,22, +147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202, +192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,2,27,248,22, 182,3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197, -2,27,248,22,181,3,23,195,2,249,22,183,15,27,251,22,154,8,250,22,153, +2,27,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153, 8,23,205,2,39,23,204,1,2,71,249,22,153,8,23,204,1,23,202,1,28, 248,22,153,7,23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248, -22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,182,11,2,37, -2,69,2,70,202,192,28,248,22,174,15,198,248,22,175,15,198,247,22,176,15, +22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37, +2,69,2,70,202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15, 28,248,22,133,4,193,253,2,175,2,199,200,201,248,22,147,8,200,2,51,248, 22,147,8,200,27,248,22,182,3,194,28,249,22,169,9,8,46,249,22,148,8, 198,196,253,2,175,2,200,201,202,198,2,71,248,22,181,3,199,251,2,174,2, -198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,174,15, -23,196,2,10,28,248,22,173,15,23,196,2,10,28,248,22,153,7,23,196,2, -28,248,22,132,16,23,196,2,10,248,22,133,16,23,196,2,11,12,252,22,180, +198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,175,15, +23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2, +28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,12,252,22,181, 11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7,23,197,2, -10,248,22,142,8,23,197,2,12,252,22,180,11,2,37,2,72,40,23,200,2, -23,201,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,199,2,86,94, -23,195,1,86,94,28,192,12,250,22,183,11,2,37,2,73,23,201,2,249,22, -7,194,195,27,248,22,179,15,23,196,1,27,251,2,174,2,23,198,2,23,201, -1,23,202,1,248,22,147,8,23,199,1,28,248,22,174,15,195,249,22,191,15, +10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72,40,23,200,2, +23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,199,2,86,94, +23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23,201,2,249,22, +7,194,195,27,248,22,180,15,23,196,1,27,251,2,174,2,23,198,2,23,201, +1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195,249,22,128,16, 196,194,192,252,80,144,44,8,35,42,2,37,2,71,22,153,8,198,199,249,247, 22,176,5,23,195,1,11,249,247,22,176,5,194,11,28,248,22,88,23,195,2, -9,27,27,248,22,81,23,197,2,28,248,22,134,16,23,194,2,248,22,137,16, -23,194,1,28,248,22,133,16,23,194,2,90,144,42,11,89,146,42,39,11,248, -22,130,16,249,22,135,16,250,80,144,50,43,42,248,22,150,16,2,56,11,11, -248,22,150,16,2,57,86,95,23,195,1,23,194,1,248,22,137,16,249,22,135, -16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,150,16,2,56,23, -197,1,10,28,23,193,2,248,22,137,16,23,194,1,11,28,23,193,2,249,22, -80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,27,248,22,162,20, +9,27,27,248,22,81,23,197,2,28,248,22,135,16,23,194,2,248,22,138,16, +23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248, +22,131,16,249,22,136,16,250,80,144,50,43,42,248,22,151,16,2,56,11,11, +248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136, +16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,151,16,2,56,23, +197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28,23,193,2,249,22, +80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,27,248,22,163,20, 23,199,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81, -23,196,2,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1, -247,22,151,16,248,80,144,47,8,50,42,248,22,162,20,23,198,1,86,94,23, -193,1,248,80,144,45,8,50,42,248,22,162,20,23,196,1,86,94,23,193,1, -27,248,22,162,20,23,197,1,28,248,22,88,23,194,2,9,27,248,80,144,43, -56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,137,16,249,22, -135,16,23,198,1,247,22,151,16,248,80,144,45,8,50,42,248,22,162,20,23, -198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,162,20,23,196,1, -28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,134,16, -23,194,2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42, -11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,50,43,42,248, -22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1, -248,22,137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,45,43,42, -248,22,150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1, -11,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22, -151,16,27,248,22,162,20,23,199,1,28,248,22,88,23,194,2,9,27,248,80, -144,45,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,137,16, -249,22,135,16,23,198,1,247,22,151,16,248,80,144,47,8,51,42,248,22,162, -20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,162,20,23, -196,1,86,94,23,193,1,27,248,22,162,20,23,197,1,28,248,22,88,23,194, +23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1, +247,22,152,16,248,80,144,47,8,50,42,248,22,163,20,23,198,1,86,94,23, +193,1,248,80,144,45,8,50,42,248,22,163,20,23,196,1,86,94,23,193,1, +27,248,22,163,20,23,197,1,28,248,22,88,23,194,2,9,27,248,80,144,43, +56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22, +136,16,23,198,1,247,22,152,16,248,80,144,45,8,50,42,248,22,163,20,23, +198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,163,20,23,196,1, +28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,135,16, +23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42, +11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,50,43,42,248, +22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1, +248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,45,43,42, +248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1, +11,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22, +152,16,27,248,22,163,20,23,199,1,28,248,22,88,23,194,2,9,27,248,80, +144,45,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138,16, +249,22,136,16,23,198,1,247,22,152,16,248,80,144,47,8,51,42,248,22,163, +20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,163,20,23, +196,1,86,94,23,193,1,27,248,22,163,20,23,197,1,28,248,22,88,23,194, 2,9,27,248,80,144,43,56,42,248,22,81,23,196,2,28,23,193,2,249,22, -80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248,80,144,45,8, -51,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42, -248,22,162,20,23,196,1,27,248,22,150,16,2,58,28,248,22,134,16,23,194, -2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42,11,89, -146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,49,43,42,248,22,150, -16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1,248,22, -137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, -150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1,11,28, -248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,134,16,23, -194,2,248,22,137,16,23,194,1,28,248,22,133,16,23,194,2,90,144,42,11, -89,146,42,39,11,248,22,130,16,249,22,135,16,250,80,144,50,43,42,248,22, -150,16,2,56,11,11,248,22,150,16,2,57,86,95,23,195,1,23,194,1,248, -22,137,16,249,22,135,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248, -22,150,16,2,56,23,197,1,10,28,23,193,2,248,22,137,16,23,194,1,11, -28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151, -16,27,248,22,162,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248,22, -81,23,196,2,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248, -22,133,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22, -135,16,250,80,144,54,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2, -57,86,95,23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23, -196,1,27,250,80,144,49,43,42,248,22,150,16,2,56,23,197,1,10,28,23, -193,2,248,22,137,16,23,194,1,11,28,23,193,2,249,22,80,248,22,137,16, -249,22,135,16,23,198,1,247,22,151,16,27,248,22,162,20,23,198,1,28,248, +80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,45,8, +51,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42, +248,22,163,20,23,196,1,27,248,22,151,16,2,58,28,248,22,135,16,23,194, +2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89, +146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22,151, +16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22, +138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, +151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28, +248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,135,16,23, +194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11, +89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,50,43,42,248,22, +151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248, +22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248, +22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11, +28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152, +16,27,248,22,163,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248,22, +81,23,196,2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248, +22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22, +136,16,250,80,144,54,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2, +57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23, +196,1,27,250,80,144,49,43,42,248,22,151,16,2,56,23,197,1,10,28,23, +193,2,248,22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16, +249,22,136,16,23,198,1,247,22,152,16,27,248,22,163,20,23,198,1,28,248, 22,88,23,194,2,9,27,248,80,144,49,56,42,248,22,81,23,196,2,28,23, -193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248, -80,144,51,8,53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144, -49,8,53,42,248,22,162,20,23,196,1,86,94,23,193,1,27,248,22,162,20, +193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248, +80,144,51,8,53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144, +49,8,53,42,248,22,163,20,23,196,1,86,94,23,193,1,27,248,22,163,20, 23,196,1,28,248,22,88,23,194,2,9,27,248,80,144,47,56,42,248,22,81, -23,196,2,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1, -247,22,151,16,248,80,144,49,8,53,42,248,22,162,20,23,198,1,86,94,23, -193,1,248,80,144,47,8,53,42,248,22,162,20,23,196,1,86,94,23,193,1, -27,248,22,162,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22,81, -23,196,2,28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248,22, -133,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135, -16,250,80,144,52,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57, -86,95,23,195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23,196, -1,27,250,80,144,47,43,42,248,22,150,16,2,56,23,197,1,10,28,23,193, -2,248,22,137,16,23,194,1,11,28,23,193,2,249,22,80,248,22,137,16,249, -22,135,16,23,198,1,247,22,151,16,27,248,22,162,20,23,198,1,28,248,22, +23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1, +247,22,152,16,248,80,144,49,8,53,42,248,22,163,20,23,198,1,86,94,23, +193,1,248,80,144,47,8,53,42,248,22,163,20,23,196,1,86,94,23,193,1, +27,248,22,163,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22,81, +23,196,2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22, +134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136, +16,250,80,144,52,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57, +86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196, +1,27,250,80,144,47,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193, +2,248,22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16,249, +22,136,16,23,198,1,247,22,152,16,27,248,22,163,20,23,198,1,28,248,22, 88,23,194,2,9,27,248,80,144,47,56,42,248,22,81,23,196,2,28,23,193, -2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248,80, -144,49,8,53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144,47, -8,53,42,248,22,162,20,23,196,1,86,94,23,193,1,27,248,22,162,20,23, +2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80, +144,49,8,53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144,47, +8,53,42,248,22,163,20,23,196,1,86,94,23,193,1,27,248,22,163,20,23, 196,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81,23, -196,2,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247, -22,151,16,248,80,144,47,8,53,42,248,22,162,20,23,198,1,86,94,23,193, -1,248,80,144,45,8,53,42,248,22,162,20,23,196,1,27,247,22,158,16,27, +196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247, +22,152,16,248,80,144,47,8,53,42,248,22,163,20,23,198,1,86,94,23,193, +1,248,80,144,45,8,53,42,248,22,163,20,23,196,1,27,247,22,159,16,27, 248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44,41,28,23,196, 2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63, 2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1, -250,22,191,15,248,22,150,16,2,61,250,22,158,2,23,205,1,2,59,247,22, +250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247,22, 171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,50,42,250,22,94, -9,248,22,90,248,22,150,16,2,55,9,28,193,249,22,80,195,194,192,27,247, -22,158,16,27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44, +9,248,22,90,248,22,151,16,2,55,9,28,193,249,22,80,195,194,192,27,247, +22,159,16,27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44, 41,28,23,196,2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165, 8,194,7,63,2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27, -28,23,200,1,250,22,191,15,248,22,150,16,2,61,250,22,158,2,23,205,1, +28,23,200,1,250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205,1, 2,59,247,22,171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,51, -42,250,22,94,23,207,1,248,22,90,248,22,150,16,2,55,9,28,193,249,22, -80,195,194,192,27,247,22,158,16,27,248,80,144,42,58,42,249,80,144,44,55, +42,250,22,94,23,207,1,248,22,90,248,22,151,16,2,55,9,28,193,249,22, +80,195,194,192,27,247,22,159,16,27,248,80,144,42,58,42,249,80,144,44,55, 40,40,80,144,44,8,52,42,249,80,144,43,44,41,28,23,196,2,27,249,22, 175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63,2,66,2,66, -250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1,250,22,191,15, -248,22,150,16,2,61,250,22,158,2,23,205,1,2,59,247,22,171,8,2,77, -86,94,23,199,1,11,27,27,250,22,94,23,207,1,248,22,90,248,22,150,16, +250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1,250,22,128,16, +248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247,22,171,8,2,77, +86,94,23,199,1,11,27,27,250,22,94,23,207,1,248,22,90,248,22,151,16, 2,55,23,208,1,28,248,22,88,23,194,2,9,27,27,248,22,81,23,196,2, -28,248,22,134,16,23,194,2,248,22,137,16,23,194,1,28,248,22,133,16,23, -194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,249,22,135,16,250,80, -144,60,43,42,248,22,150,16,2,56,11,11,248,22,150,16,2,57,86,95,23, -195,1,23,194,1,248,22,137,16,249,22,135,16,23,199,1,23,196,1,27,250, -80,144,55,43,42,248,22,150,16,2,56,23,197,1,10,28,23,193,2,248,22, -137,16,23,194,1,11,28,23,193,2,249,22,80,248,22,137,16,249,22,135,16, -23,198,1,247,22,151,16,27,248,22,162,20,23,198,1,28,248,22,88,23,194, +28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23, +194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80, +144,60,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23, +195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250, +80,144,55,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22, +138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16, +23,198,1,247,22,152,16,27,248,22,163,20,23,198,1,28,248,22,88,23,194, 2,9,27,248,80,144,55,56,42,248,22,81,23,196,2,28,23,193,2,249,22, -80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16,248,80,144,57,8, -53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42, -248,22,162,20,23,196,1,86,94,23,193,1,27,248,22,162,20,23,196,1,28, +80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,57,8, +53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42, +248,22,163,20,23,196,1,86,94,23,193,1,27,248,22,163,20,23,196,1,28, 248,22,88,23,194,2,9,27,248,80,144,53,56,42,248,22,81,23,196,2,28, -23,193,2,249,22,80,248,22,137,16,249,22,135,16,23,198,1,247,22,151,16, -248,80,144,55,8,53,42,248,22,162,20,23,198,1,86,94,23,193,1,248,80, -144,53,8,53,42,248,22,162,20,23,196,1,28,193,249,22,80,195,194,192,27, +23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16, +248,80,144,55,8,53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80, +144,53,8,53,42,248,22,163,20,23,196,1,28,193,249,22,80,195,194,192,27, 20,13,144,80,144,40,46,40,26,9,80,144,49,47,40,249,22,31,11,80,144, -51,46,40,22,147,15,10,22,154,15,10,22,155,15,10,22,156,15,10,248,22, +51,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157,15,10,248,22, 148,6,23,196,2,28,248,22,148,7,23,194,2,12,86,94,248,22,177,9,23, 194,1,27,20,13,144,80,144,41,46,40,26,9,80,144,50,47,40,249,22,31, -11,80,144,52,46,40,22,147,15,10,22,154,15,10,22,155,15,10,22,156,15, +11,80,144,52,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157,15, 10,248,22,148,6,23,197,2,28,248,22,148,7,23,194,2,12,86,94,248,22, 177,9,23,194,1,27,20,13,144,80,144,42,46,40,26,9,80,144,51,47,40, -249,22,31,11,80,144,53,46,40,22,147,15,10,22,154,15,10,22,155,15,10, -22,156,15,10,248,22,148,6,23,198,2,28,248,22,148,7,23,194,2,12,86, +249,22,31,11,80,144,53,46,40,22,148,15,10,22,155,15,10,22,156,15,10, +22,157,15,10,248,22,148,6,23,198,2,28,248,22,148,7,23,194,2,12,86, 94,248,22,177,9,23,194,1,248,80,144,43,8,54,42,197,86,94,249,22,139, 7,247,22,172,5,23,196,2,248,22,163,6,249,22,136,4,39,249,22,184,3, 28,23,198,2,23,198,1,86,94,23,198,1,39,23,199,1,27,248,22,189,5, 28,23,198,2,86,95,23,197,1,23,196,1,23,198,1,86,94,23,198,1,27, -250,80,144,45,43,42,248,22,150,16,2,56,11,11,27,248,22,139,4,23,199, +250,80,144,45,43,42,248,22,151,16,2,56,11,11,27,248,22,139,4,23,199, 1,27,28,23,194,2,23,194,1,86,94,23,194,1,39,27,248,22,139,4,23, 202,1,249,22,140,6,23,198,1,20,20,95,88,148,8,36,39,51,11,9,224, 3,2,33,190,2,23,195,1,23,196,1,248,80,144,41,8,54,42,193,144,39, @@ -973,7 +973,7 @@ 40,20,15,16,2,88,148,8,36,41,61,41,2,6,223,0,33,85,80,144,39, 42,40,20,15,16,2,20,26,96,2,7,88,148,8,36,42,8,24,8,32,9, 223,0,33,92,88,148,8,36,41,50,55,9,223,0,33,93,88,148,8,36,40, -49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,162,16, +49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,163,16, 248,22,167,8,27,28,249,22,169,9,247,22,180,8,2,43,6,1,1,59,6, 1,1,58,250,22,137,8,6,14,14,40,91,94,126,97,93,42,41,126,97,40, 46,42,41,23,196,2,23,196,1,88,148,8,36,41,51,11,2,8,223,0,33, @@ -1046,7 +1046,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 19759); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,8,0, 23,0,48,0,65,0,83,0,105,0,128,0,149,0,171,0,180,0,189,0,196, 0,205,0,212,0,0,0,247,1,0,0,3,1,5,105,110,115,112,48,76,35, @@ -1066,8 +1066,8 @@ 16,2,2,6,2,7,41,11,11,11,16,5,2,4,2,8,2,9,2,5,2, 3,16,5,11,11,11,11,11,16,5,2,4,2,8,2,9,2,5,2,3,44, 44,40,12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0, -16,0,39,39,16,3,20,15,16,6,253,22,188,10,2,4,11,41,39,11,248, -22,90,249,22,80,22,174,10,88,148,39,40,48,47,9,223,9,33,10,80,144, +16,0,39,39,16,3,20,15,16,6,253,22,189,10,2,4,11,41,39,11,248, +22,90,249,22,80,22,175,10,88,148,39,40,48,47,9,223,9,33,10,80,144, 39,39,40,80,144,39,40,40,80,144,39,41,40,80,144,39,42,40,80,144,39, 43,40,20,15,16,2,20,28,143,88,148,39,40,48,47,9,223,0,33,11,88, 148,39,40,48,47,9,223,0,33,12,80,144,39,44,40,20,15,16,2,20,28, @@ -1077,7 +1077,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 577); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,1,0,0,8,0, 15,0,26,0,53,0,59,0,73,0,86,0,112,0,129,0,151,0,159,0,171, 0,186,0,202,0,220,0,241,0,253,0,13,1,36,1,60,1,72,1,103,1, @@ -1112,64 +1112,64 @@ 12,12,109,111,100,117,108,101,45,112,97,116,104,63,68,115,117,98,109,111,100, 6,2,2,46,46,6,1,1,46,66,102,105,108,101,68,112,108,97,110,101,116, 6,8,8,109,97,105,110,46,114,107,116,6,4,4,46,114,107,116,69,105,103, -110,111,114,101,100,27,252,22,191,15,28,249,22,169,9,23,201,2,2,27,86, -94,23,199,1,23,200,1,28,248,22,132,16,23,200,2,249,22,191,15,23,202, +110,111,114,101,100,27,252,22,128,16,28,249,22,169,9,23,201,2,2,27,86, +94,23,199,1,23,200,1,28,248,22,133,16,23,200,2,249,22,128,16,23,202, 1,23,201,1,249,80,144,50,45,42,23,202,1,23,201,1,23,203,1,2,28, 247,22,181,8,249,80,144,50,46,42,23,203,1,80,144,50,39,41,27,250,22, -145,16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80, +146,16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80, 195,194,11,249,22,5,20,20,96,88,148,8,36,40,57,8,129,3,9,226,5, -4,3,6,33,42,23,199,1,23,196,1,23,197,1,23,195,1,27,252,22,191, -15,28,249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28,248, -22,132,16,23,200,2,249,22,191,15,23,202,1,23,201,1,249,80,144,50,45, +4,3,6,33,42,23,199,1,23,196,1,23,197,1,23,195,1,27,252,22,128, +16,28,249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28,248, +22,133,16,23,200,2,249,22,128,16,23,202,1,23,201,1,249,80,144,50,45, 42,23,202,1,23,201,1,23,203,1,2,28,247,22,181,8,249,80,144,50,46, -42,23,203,1,80,144,50,39,41,27,250,22,145,16,196,11,32,0,88,148,8, +42,23,203,1,80,144,50,39,41,27,250,22,146,16,196,11,32,0,88,148,8, 36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5,20,20,96, 88,148,8,36,40,57,8,129,3,9,226,5,4,3,6,33,44,23,199,1,23, -196,1,23,197,1,23,195,1,27,250,22,191,15,28,249,22,169,9,23,199,2, -2,27,86,94,23,197,1,23,198,1,28,248,22,132,16,23,198,2,249,22,191, -15,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23,201, -1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,145,16,196,11,32,0, +196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169,9,23,199,2, +2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198,2,249,22,128, +16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23,201, +1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16,196,11,32,0, 88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5, 20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6,33,46,23, -199,1,23,196,1,23,197,1,23,195,1,27,250,22,191,15,28,249,22,169,9, -23,199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,132,16,23,198,2, -249,22,191,15,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199, -1,23,201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,145,16,196, +199,1,23,196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169,9, +23,199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198,2, +249,22,128,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199, +1,23,201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16,196, 11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11, 249,22,5,20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6, 33,48,23,199,1,23,196,1,23,197,1,23,195,1,86,95,28,248,80,144,40, -43,42,23,195,2,12,250,22,180,11,2,25,6,12,12,112,97,116,104,45,115, +43,42,23,195,2,12,250,22,181,11,2,25,6,12,12,112,97,116,104,45,115, 116,114,105,110,103,63,23,197,2,28,28,23,195,2,28,248,22,64,23,196,2, 10,28,248,22,89,23,196,2,28,249,22,130,4,248,22,93,23,198,2,40,28, -28,248,22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,161,20,23,197, -2,249,22,4,22,64,248,22,162,20,23,198,2,11,11,11,10,12,250,22,180, +28,248,22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,162,20,23,197, +2,249,22,4,22,64,248,22,163,20,23,198,2,11,11,11,10,12,250,22,181, 11,2,25,6,71,71,40,111,114,47,99,32,35,102,32,115,121,109,98,111,108, 63,32,40,99,111,110,115,47,99,32,40,111,114,47,99,32,35,102,32,115,121, 109,98,111,108,63,41,32,40,110,111,110,45,101,109,112,116,121,45,108,105,115, 116,111,102,32,115,121,109,98,111,108,63,41,41,41,23,197,2,27,28,23,196, 2,247,22,191,4,11,27,28,23,194,2,250,22,158,2,80,143,44,44,248,22, -191,16,247,22,143,14,11,11,27,28,23,194,2,250,22,158,2,248,22,82,23, +128,17,247,22,144,14,11,11,27,28,23,194,2,250,22,158,2,248,22,82,23, 198,2,23,198,2,11,11,28,23,193,2,86,96,23,197,1,23,195,1,23,194, 1,20,13,144,80,144,42,41,40,250,80,144,45,42,40,249,22,31,11,80,144, 47,41,40,22,128,5,248,22,102,23,197,2,27,248,22,111,23,195,2,20,13, 144,80,144,43,41,40,250,80,144,46,42,40,249,22,31,11,80,144,48,41,40, -22,177,5,28,248,22,173,15,23,197,2,23,196,1,86,94,23,196,1,247,22, -151,16,249,247,22,175,5,248,22,161,20,23,197,1,23,201,1,86,94,23,193, -1,27,28,248,22,134,16,23,199,2,23,198,2,27,247,22,177,5,28,192,249, -22,135,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22, -130,16,23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28,23, -204,2,27,248,22,178,15,23,198,2,19,248,22,147,8,194,28,28,249,22,132, +22,177,5,28,248,22,174,15,23,197,2,23,196,1,86,94,23,196,1,247,22, +152,16,249,247,22,175,5,248,22,162,20,23,197,1,23,201,1,86,94,23,193, +1,27,28,248,22,135,16,23,199,2,23,198,2,27,247,22,177,5,28,192,249, +22,136,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22, +131,16,23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28,23, +204,2,27,248,22,179,15,23,198,2,19,248,22,147,8,194,28,28,249,22,132, 4,23,195,4,43,249,22,150,8,2,26,249,22,153,8,197,249,22,184,3,23, -199,4,43,11,249,22,7,23,200,2,248,22,182,15,249,22,154,8,250,22,153, +199,4,43,11,249,22,7,23,200,2,248,22,183,15,249,22,154,8,250,22,153, 8,201,39,249,22,184,3,23,203,4,43,5,3,46,115,115,249,22,7,23,200, 2,11,2,249,22,7,23,198,2,11,27,28,249,22,169,9,23,196,2,23,199, -2,23,199,2,249,22,191,15,23,198,2,23,196,2,27,28,23,196,2,28,249, -22,169,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,191,15, +2,23,199,2,249,22,128,16,23,198,2,23,196,2,27,28,23,196,2,28,249, +22,169,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,128,16, 23,199,2,23,198,2,86,94,23,198,1,11,27,28,249,22,169,9,23,200,2, 70,114,101,108,97,116,105,118,101,86,94,23,198,1,2,27,23,198,1,27,247, -22,156,16,27,247,22,157,16,27,250,22,145,16,23,201,2,11,32,0,88,148, +22,157,16,27,247,22,158,16,27,250,22,146,16,23,201,2,11,32,0,88,148, 8,36,39,44,11,9,222,11,27,28,23,194,2,249,22,80,23,201,2,23,196, -1,86,94,23,194,1,11,27,28,23,199,2,28,23,194,2,11,27,250,22,145, +1,86,94,23,194,1,11,27,28,23,199,2,28,23,194,2,11,27,250,22,146, 16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22, 80,23,202,2,194,11,11,27,28,23,195,2,23,195,2,23,194,2,27,28,23, 196,2,23,196,2,248,22,167,9,23,196,2,27,28,23,205,2,28,23,196,2, @@ -1181,8 +1181,8 @@ 201,1,23,200,1,23,197,1,23,196,1,23,195,1,23,194,1,20,13,144,80, 144,60,41,40,250,80,144,8,24,42,40,249,22,31,11,80,144,8,26,41,40, 22,128,5,11,20,13,144,80,144,60,41,40,250,80,144,8,24,42,40,249,22, -31,11,80,144,8,26,41,40,22,177,5,28,248,22,173,15,23,206,2,23,205, -1,86,94,23,205,1,247,22,151,16,249,247,22,161,16,248,22,81,23,196,1, +31,11,80,144,8,26,41,40,22,177,5,28,248,22,174,15,23,206,2,23,205, +1,86,94,23,205,1,247,22,152,16,249,247,22,162,16,248,22,81,23,196,1, 23,218,1,86,94,23,193,1,27,28,23,195,2,27,249,22,5,88,148,39,40, 51,8,129,3,9,226,25,17,13,12,33,45,23,204,2,27,28,23,200,2,11, 193,28,192,192,28,193,28,199,28,249,22,132,4,248,22,82,196,248,22,82,202, @@ -1190,8 +1190,8 @@ 206,1,23,205,1,23,202,1,23,201,1,23,197,1,23,196,1,23,195,1,20, 13,144,80,144,61,41,40,250,80,144,8,25,42,40,249,22,31,11,80,144,8, 27,41,40,22,128,5,23,207,1,20,13,144,80,144,61,41,40,250,80,144,8, -25,42,40,249,22,31,11,80,144,8,27,41,40,22,177,5,28,248,22,173,15, -23,207,2,23,206,1,86,94,23,206,1,247,22,151,16,249,247,22,161,16,248, +25,42,40,249,22,31,11,80,144,8,27,41,40,22,177,5,28,248,22,174,15, +23,207,2,23,206,1,86,94,23,206,1,247,22,152,16,249,247,22,162,16,248, 22,81,23,196,1,23,219,1,86,94,23,193,1,27,28,23,197,2,27,249,22, 5,20,20,94,88,148,39,40,51,8,128,3,9,226,26,17,14,13,33,47,23, 210,1,23,205,2,27,28,23,200,2,11,193,28,192,192,28,193,28,23,200,2, @@ -1202,8 +1202,8 @@ 23,199,1,11,23,211,2,12,20,13,144,80,144,8,23,41,40,250,80,144,8, 26,42,40,249,22,31,11,80,144,8,28,41,40,22,128,5,11,20,13,144,80, 144,8,23,41,40,250,80,144,8,26,42,40,249,22,31,11,80,144,8,28,41, -40,22,177,5,28,248,22,173,15,23,208,2,23,207,1,86,94,23,207,1,247, -22,151,16,249,247,22,175,5,248,22,161,20,23,196,1,23,220,1,86,94,23, +40,22,177,5,28,248,22,174,15,23,208,2,23,207,1,86,94,23,207,1,247, +22,152,16,249,247,22,175,5,248,22,162,20,23,196,1,23,220,1,86,94,23, 193,1,27,28,23,197,1,27,249,22,5,20,20,95,88,148,39,40,51,8,128, 3,9,226,27,19,15,14,33,49,23,207,1,23,212,1,23,206,1,27,28,23, 201,2,11,193,28,192,192,28,193,28,200,28,249,22,132,4,248,22,82,196,248, @@ -1213,16 +1213,16 @@ 23,213,2,23,212,2,12,20,13,144,80,144,8,24,41,40,250,80,144,8,27, 42,40,249,22,31,11,80,144,8,29,41,40,22,128,5,23,209,1,20,13,144, 80,144,8,24,41,40,250,80,144,8,27,42,40,249,22,31,11,80,144,8,29, -41,40,22,177,5,28,248,22,173,15,23,209,2,23,208,1,86,94,23,208,1, -247,22,151,16,249,247,22,175,5,248,22,161,20,23,196,1,23,221,1,86,94, -23,193,1,28,28,248,22,78,23,220,2,248,22,161,20,23,220,2,10,27,28, +41,40,22,177,5,28,248,22,174,15,23,209,2,23,208,1,86,94,23,208,1, +247,22,152,16,249,247,22,175,5,248,22,162,20,23,196,1,23,221,1,86,94, +23,193,1,28,28,248,22,78,23,220,2,248,22,162,20,23,220,2,10,27,28, 23,199,2,86,94,23,207,1,23,208,1,86,94,23,208,1,23,207,1,28,28, -248,22,78,23,221,2,248,22,167,9,248,22,185,15,23,195,2,11,12,20,13, +248,22,78,23,221,2,248,22,167,9,248,22,186,15,23,195,2,11,12,20,13, 144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22,31,11,80,144,8, 30,41,40,22,128,5,28,23,223,2,28,23,202,1,11,23,196,2,86,94,23, 202,1,11,20,13,144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22, -31,11,80,144,8,30,41,40,22,177,5,28,248,22,173,15,23,210,2,23,209, -1,86,94,23,209,1,247,22,151,16,249,247,22,175,5,23,195,1,23,222,1, +31,11,80,144,8,30,41,40,22,177,5,28,248,22,174,15,23,210,2,23,209, +1,86,94,23,209,1,247,22,152,16,249,247,22,175,5,23,195,1,23,222,1, 12,28,23,194,2,250,22,156,2,248,22,82,23,198,1,23,196,1,250,22,90, 23,201,1,23,202,1,23,203,1,12,27,249,22,189,8,80,144,42,50,41,249, 22,191,3,248,22,187,3,248,22,173,2,200,8,128,8,27,28,193,248,22,176, @@ -1286,22 +1286,22 @@ 23,200,2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181,3, 23,199,1,250,2,54,23,197,4,197,248,22,181,3,196,32,70,88,148,39,40, 58,11,2,31,222,33,71,28,248,22,88,248,22,82,23,195,2,249,22,7,9, -248,22,161,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,162,20, -23,197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,161,20, -195,90,144,41,11,89,146,41,39,11,27,248,22,162,20,196,28,248,22,88,248, -22,82,23,195,2,249,22,7,9,248,22,161,20,195,90,144,41,11,89,146,41, -39,11,248,2,70,248,22,162,20,196,249,22,7,249,22,80,248,22,161,20,199, -196,195,249,22,7,249,22,80,248,22,161,20,199,196,195,249,22,7,249,22,80, -248,22,161,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23,196, +248,22,162,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,163,20, +23,197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,162,20, +195,90,144,41,11,89,146,41,39,11,27,248,22,163,20,196,28,248,22,88,248, +22,82,23,195,2,249,22,7,9,248,22,162,20,195,90,144,41,11,89,146,41, +39,11,248,2,70,248,22,163,20,196,249,22,7,249,22,80,248,22,162,20,199, +196,195,249,22,7,249,22,80,248,22,162,20,199,196,195,249,22,7,249,22,80, +248,22,162,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23,196, 2,250,2,54,23,196,4,23,198,1,39,2,28,23,195,1,192,28,248,22,88, -248,22,82,23,195,2,249,22,7,9,248,22,161,20,23,196,1,27,248,22,162, +248,22,82,23,195,2,249,22,7,9,248,22,162,20,23,196,1,27,248,22,163, 20,23,195,2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23, -197,2,249,22,7,9,248,22,161,20,23,198,1,27,248,22,162,20,23,197,2, +197,2,249,22,7,9,248,22,162,20,23,198,1,27,248,22,163,20,23,197,2, 90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23,197,2,249,22, -7,9,248,22,161,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22, -162,20,198,249,22,7,249,22,80,248,22,161,20,201,196,195,249,22,7,249,22, -80,248,22,161,20,23,203,1,196,195,249,22,7,249,22,80,248,22,161,20,23, -201,1,23,197,1,23,196,1,248,22,142,12,252,22,161,10,248,22,163,4,23, +7,9,248,22,162,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22, +163,20,198,249,22,7,249,22,80,248,22,162,20,201,196,195,249,22,7,249,22, +80,248,22,162,20,23,203,1,196,195,249,22,7,249,22,80,248,22,162,20,23, +201,1,23,197,1,23,196,1,248,22,143,12,252,22,162,10,248,22,163,4,23, 200,2,248,22,159,4,23,200,2,248,22,160,4,23,200,2,248,22,161,4,23, 200,2,248,22,162,4,23,200,1,28,24,194,2,12,20,13,144,80,144,39,41, 40,80,143,39,59,89,146,40,40,10,249,22,130,5,21,94,2,32,6,19,19, @@ -1309,29 +1309,29 @@ 112,108,97,110,101,116,45,109,111,100,117,108,101,45,110,97,109,101,45,114,101, 115,111,108,118,101,114,12,27,28,23,195,2,28,249,22,169,9,23,197,2,80, 143,42,55,86,94,23,195,1,80,143,40,56,27,248,22,153,5,23,197,2,27, -28,248,22,78,23,195,2,248,22,161,20,23,195,1,23,194,1,28,248,22,173, -15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,130,16,23,197,1,86, +28,248,22,78,23,195,2,248,22,162,20,23,195,1,23,194,1,28,248,22,174, +15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86, 95,20,18,144,11,80,143,45,55,199,20,18,144,11,80,143,45,56,192,192,11, 11,28,23,193,2,192,86,94,23,193,1,27,247,22,177,5,28,23,193,2,192, -86,94,23,193,1,247,22,151,16,90,144,42,11,89,146,42,39,11,248,22,130, -16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,166,16,0,11,35,114, -120,34,91,46,93,115,115,36,34,248,22,178,15,23,197,1,249,80,144,44,61, +86,94,23,193,1,247,22,152,16,90,144,42,11,89,146,42,39,11,248,22,131, +16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,167,16,0,11,35,114, +120,34,91,46,93,115,115,36,34,248,22,179,15,23,197,1,249,80,144,44,61, 42,23,199,1,2,26,196,249,80,144,41,57,42,195,10,249,22,12,23,196,1, -80,144,41,54,41,86,96,28,248,22,151,5,23,196,2,12,250,22,180,11,2, +80,144,41,54,41,86,96,28,248,22,151,5,23,196,2,12,250,22,181,11,2, 22,6,21,21,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45,112, -97,116,104,63,23,198,2,28,28,23,196,2,248,22,144,14,23,197,2,10,12, -250,22,180,11,2,22,6,20,20,40,111,114,47,99,32,35,102,32,110,97,109, +97,116,104,63,23,198,2,28,28,23,196,2,248,22,145,14,23,197,2,10,12, +250,22,181,11,2,22,6,20,20,40,111,114,47,99,32,35,102,32,110,97,109, 101,115,112,97,99,101,63,41,23,199,2,28,24,193,2,248,24,194,1,23,196, -2,86,94,23,193,1,12,27,250,22,158,2,80,144,44,44,41,248,22,191,16, -247,22,143,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249,22, +2,86,94,23,193,1,12,27,250,22,158,2,80,144,44,44,41,248,22,128,17, +247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249,22, 80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,46,44,41,248, -22,191,16,247,22,143,14,195,192,86,94,250,22,156,2,248,22,81,23,197,2, +22,128,17,247,22,144,14,195,192,86,94,250,22,156,2,248,22,81,23,197,2, 23,200,2,70,100,101,99,108,97,114,101,100,28,23,198,2,27,28,248,22,78, 248,22,153,5,23,200,2,248,22,152,5,248,22,81,248,22,153,5,23,201,1, -23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,191,16,23,204,1,11, +23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,128,17,23,204,1,11, 28,23,193,2,27,250,22,158,2,248,22,82,23,198,1,23,198,2,11,28,23, -193,2,250,22,156,2,248,22,162,20,23,200,1,23,198,1,23,196,1,12,12, -12,86,94,251,22,137,12,247,22,141,12,67,101,114,114,111,114,6,69,69,100, +193,2,250,22,156,2,248,22,163,20,23,200,1,23,198,1,23,196,1,12,12, +12,86,94,251,22,138,12,247,22,142,12,67,101,114,114,111,114,6,69,69,100, 101,102,97,117,108,116,32,109,111,100,117,108,101,32,110,97,109,101,32,114,101, 115,111,108,118,101,114,32,99,97,108,108,101,100,32,119,105,116,104,32,116,104, 114,101,101,32,97,114,103,117,109,101,110,116,115,32,40,100,101,112,114,101,99, @@ -1340,20 +1340,20 @@ 97,116,104,222,33,84,32,82,88,148,39,43,57,11,2,31,222,33,83,28,248, 22,88,23,197,2,28,248,22,88,195,192,249,22,80,194,248,22,95,197,28,249, 22,171,9,248,22,81,23,199,2,2,35,28,248,22,88,23,196,2,86,95,23, -196,1,23,195,1,250,22,176,11,2,22,6,37,37,116,111,111,32,109,97,110, +196,1,23,195,1,250,22,177,11,2,22,6,37,37,116,111,111,32,109,97,110, 121,32,34,46,46,34,115,32,105,110,32,115,117,98,109,111,100,117,108,101,32, 112,97,116,104,58,32,126,46,115,250,22,91,2,34,28,249,22,171,9,23,201, -2,2,36,23,199,1,28,248,22,173,15,23,200,2,23,199,1,249,22,90,28, +2,2,36,23,199,1,28,248,22,174,15,23,200,2,23,199,1,249,22,90,28, 248,22,64,23,202,2,2,5,2,37,23,201,1,23,200,1,251,2,82,196,197, -248,22,82,199,248,22,162,20,200,251,2,82,196,197,249,22,80,248,22,161,20, -202,200,248,22,162,20,200,251,2,82,196,197,9,197,27,250,22,176,7,27,28, -23,199,2,28,247,22,129,12,248,80,144,47,58,42,23,200,2,11,11,28,192, +248,22,82,199,248,22,163,20,200,251,2,82,196,197,249,22,80,248,22,162,20, +202,200,248,22,163,20,200,251,2,82,196,197,9,197,27,250,22,176,7,27,28, +23,199,2,28,247,22,130,12,248,80,144,47,58,42,23,200,2,11,11,28,192, 192,6,29,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110, -97,109,101,45,114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,177,16, +97,109,101,45,114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,178,16, 0,7,35,114,120,34,92,110,34,23,203,1,249,22,137,8,6,23,23,10,32, 32,102,111,114,32,109,111,100,117,108,101,32,112,97,116,104,58,32,126,115,10, -23,202,2,248,22,172,13,28,23,196,2,251,22,180,12,23,198,1,247,22,27, -248,22,90,23,201,1,23,199,1,86,94,23,196,1,250,22,143,13,23,197,1, +23,202,2,248,22,173,13,28,23,196,2,251,22,181,12,23,198,1,247,22,27, +248,22,90,23,201,1,23,199,1,86,94,23,196,1,250,22,144,13,23,197,1, 247,22,27,23,198,1,32,86,88,148,8,36,40,53,11,69,115,115,45,62,114, 107,116,222,33,87,19,248,22,156,7,194,28,249,22,132,4,23,195,4,42,28, 249,22,169,9,7,46,249,22,157,7,197,249,22,184,3,23,199,4,42,28,28, @@ -1363,9 +1363,9 @@ 28,249,22,159,7,194,2,36,2,27,28,249,22,159,7,194,2,35,64,117,112, 192,0,8,35,114,120,34,91,46,93,34,32,90,88,148,8,36,40,50,11,2, 31,222,33,91,28,248,22,88,23,194,2,9,250,22,91,6,4,4,10,32,32, -32,248,22,177,15,248,22,103,23,198,2,248,2,90,248,22,162,20,23,198,1, +32,248,22,178,15,248,22,103,23,198,2,248,2,90,248,22,163,20,23,198,1, 28,249,22,171,9,248,22,82,23,200,2,23,197,1,28,249,22,169,9,248,22, -161,20,23,200,1,23,196,1,251,22,176,11,2,22,6,41,41,99,121,99,108, +162,20,23,200,1,23,196,1,251,22,177,11,2,22,6,41,41,99,121,99,108, 101,32,105,110,32,108,111,97,100,105,110,103,10,32,32,97,116,32,112,97,116, 104,58,32,126,97,10,32,32,112,97,116,104,115,58,126,97,23,200,1,249,22, 1,22,176,7,248,2,90,248,22,95,23,201,1,12,12,247,23,193,1,250,22, @@ -1374,58 +1374,58 @@ 249,22,31,11,80,144,56,41,40,22,191,4,23,201,2,22,129,5,248,28,23, 208,2,20,20,94,88,148,8,36,40,49,11,9,223,15,33,94,23,208,1,86, 94,23,208,1,22,7,28,248,22,64,23,207,2,23,206,1,28,28,248,22,78, -23,207,2,249,22,169,9,248,22,161,20,23,209,2,2,32,11,23,206,1,86, +23,207,2,249,22,169,9,248,22,162,20,23,209,2,2,32,11,23,206,1,86, 94,23,206,1,28,248,22,151,5,23,203,2,27,248,22,153,5,23,204,2,28, 248,22,64,193,249,22,90,2,5,194,192,23,202,2,249,247,22,176,5,23,201, -1,27,248,22,68,248,22,177,15,23,202,1,28,23,204,2,28,250,22,158,2, -248,22,161,20,23,202,1,23,202,1,11,249,22,80,11,205,249,22,80,194,205, +1,27,248,22,68,248,22,178,15,23,202,1,28,23,204,2,28,250,22,158,2, +248,22,162,20,23,202,1,23,202,1,11,249,22,80,11,205,249,22,80,194,205, 192,86,96,28,248,22,161,5,23,196,2,12,28,248,22,155,4,23,198,2,250, -22,178,11,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116, -104,23,200,2,250,22,180,11,2,22,2,33,23,198,2,28,28,23,196,2,248, -22,151,5,23,197,2,10,12,250,22,180,11,2,22,6,31,31,40,111,114,47, +22,179,11,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116, +104,23,200,2,250,22,181,11,2,22,2,33,23,198,2,28,28,23,196,2,248, +22,151,5,23,197,2,10,12,250,22,181,11,2,22,6,31,31,40,111,114,47, 99,32,35,102,32,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, 112,97,116,104,63,41,23,199,2,28,28,23,197,2,248,22,155,4,23,198,2, -10,12,250,22,180,11,2,22,6,17,17,40,111,114,47,99,32,35,102,32,115, +10,12,250,22,181,11,2,22,6,17,17,40,111,114,47,99,32,35,102,32,115, 121,110,116,97,120,63,41,23,200,2,28,28,248,22,78,23,196,2,249,22,169, -9,248,22,161,20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23,196, +9,248,22,162,20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23,196, 1,23,193,1,248,22,152,5,248,22,102,23,197,1,28,28,248,22,78,23,196, -2,28,249,22,169,9,248,22,161,20,23,198,2,2,34,28,248,22,78,248,22, +2,28,249,22,169,9,248,22,162,20,23,198,2,2,34,28,248,22,78,248,22, 102,23,197,2,249,22,169,9,248,22,106,23,198,2,2,5,11,11,11,86,97, 23,198,1,23,197,1,23,196,1,23,193,1,248,22,152,5,249,2,81,248,22, 119,23,199,2,248,22,104,23,199,1,28,28,248,22,78,23,196,2,28,249,22, -169,9,248,22,161,20,23,198,2,2,34,28,28,249,22,171,9,248,22,102,23, +169,9,248,22,162,20,23,198,2,2,34,28,28,249,22,171,9,248,22,102,23, 198,2,2,36,10,249,22,171,9,248,22,102,23,198,2,2,35,28,23,196,2, 27,248,22,153,5,23,198,2,28,248,22,64,193,10,28,248,22,78,193,248,22, -64,248,22,161,20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23,193, +64,248,22,162,20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23,193, 1,27,248,22,153,5,23,198,1,248,22,152,5,249,2,81,28,248,22,78,23, -197,2,248,22,161,20,23,197,2,23,196,2,27,28,249,22,171,9,248,22,102, -23,203,2,2,35,248,22,162,20,200,248,22,104,200,28,248,22,78,23,198,2, -249,22,94,248,22,162,20,199,194,192,28,28,248,22,78,23,196,2,249,22,169, -9,248,22,161,20,23,198,2,2,38,11,86,94,248,80,144,41,8,28,42,23, +197,2,248,22,162,20,23,197,2,23,196,2,27,28,249,22,171,9,248,22,102, +23,203,2,2,35,248,22,163,20,200,248,22,104,200,28,248,22,78,23,198,2, +249,22,94,248,22,163,20,199,194,192,28,28,248,22,78,23,196,2,249,22,169, +9,248,22,162,20,23,198,2,2,38,11,86,94,248,80,144,41,8,28,42,23, 194,2,253,24,199,1,23,201,1,23,202,1,23,203,1,23,204,1,11,80,143, -46,59,28,28,248,22,78,23,196,2,28,249,22,169,9,248,22,161,20,23,198, +46,59,28,28,248,22,78,23,196,2,28,249,22,169,9,248,22,162,20,23,198, 2,2,34,28,248,22,78,248,22,102,23,197,2,249,22,169,9,248,22,106,23, 198,2,2,38,11,11,11,86,94,248,80,144,41,8,28,42,23,194,2,253,24, 199,1,248,22,102,23,202,2,23,202,1,23,203,1,23,204,1,248,22,104,23, 202,1,80,143,46,59,86,94,23,193,1,27,88,148,8,36,40,57,8,240,0, 0,8,0,1,19,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110,45, 101,114,114,225,2,5,3,33,85,27,28,248,22,78,23,198,2,28,249,22,169, -9,2,34,248,22,161,20,23,200,2,27,248,22,102,23,199,2,28,28,249,22, +9,2,34,248,22,162,20,23,200,2,27,248,22,102,23,199,2,28,28,249,22, 171,9,23,195,2,2,36,10,249,22,171,9,23,195,2,2,35,86,94,23,193, -1,28,23,199,2,27,248,22,153,5,23,201,2,28,248,22,78,193,248,22,161, -20,193,192,250,22,176,11,2,22,6,45,45,110,111,32,98,97,115,101,32,112, +1,28,23,199,2,27,248,22,153,5,23,201,2,28,248,22,78,193,248,22,162, +20,193,192,250,22,177,11,2,22,6,45,45,110,111,32,98,97,115,101,32,112, 97,116,104,32,102,111,114,32,114,101,108,97,116,105,118,101,32,115,117,98,109, 111,100,117,108,101,32,112,97,116,104,58,32,126,46,115,23,201,2,192,23,197, 2,23,197,2,27,28,248,22,78,23,199,2,28,249,22,169,9,2,34,248,22, -161,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23,202,2,2,36, +162,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23,202,2,2,36, 10,249,22,171,9,248,22,102,23,202,2,2,35,23,200,2,11,27,248,22,153, -5,23,202,2,27,28,249,22,171,9,248,22,102,23,204,2,2,35,248,22,162, +5,23,202,2,27,28,249,22,171,9,248,22,102,23,204,2,2,35,248,22,163, 20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2,249,2,81,248, -22,161,20,23,197,2,249,22,94,248,22,162,20,23,199,1,23,197,1,249,2, +22,162,20,23,197,2,249,22,94,248,22,163,20,23,199,1,23,197,1,249,2, 81,23,196,1,23,195,1,249,2,81,2,36,28,249,22,171,9,248,22,102,23, -204,2,2,35,248,22,162,20,23,202,1,248,22,104,23,202,1,28,248,22,78, -193,248,22,162,20,193,11,11,11,27,28,248,22,64,23,196,2,27,248,80,144, -46,51,42,249,22,80,23,199,2,248,22,191,16,247,22,143,14,28,23,193,2, +204,2,2,35,248,22,163,20,23,202,1,248,22,104,23,202,1,28,248,22,78, +193,248,22,163,20,193,11,11,11,27,28,248,22,64,23,196,2,27,248,80,144, +46,51,42,249,22,80,23,199,2,248,22,128,17,247,22,144,14,28,23,193,2, 192,86,94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,49,57,42, 248,22,71,23,201,2,11,27,28,248,22,88,23,195,2,2,39,249,22,176,7, 23,197,2,2,40,252,80,144,53,8,23,42,23,205,1,28,248,22,88,23,200, @@ -1434,58 +1434,58 @@ 7,23,196,2,86,94,23,196,1,27,248,80,144,46,8,29,42,23,202,2,27, 248,80,144,47,51,42,249,22,80,23,200,2,23,197,2,28,23,193,2,192,86, 94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,50,57,42,23,201, -2,11,28,248,22,88,23,194,2,86,94,23,193,1,249,22,191,15,23,198,1, -248,2,86,23,197,1,250,22,1,22,191,15,23,199,1,249,22,94,249,22,2, +2,11,28,248,22,88,23,194,2,86,94,23,193,1,249,22,128,16,23,198,1, +248,2,86,23,197,1,250,22,1,22,128,16,23,199,1,249,22,94,249,22,2, 32,0,88,148,8,36,40,47,11,9,222,33,88,23,200,1,248,22,90,248,2, -86,23,201,1,28,248,22,173,15,23,196,2,86,94,23,196,1,248,80,144,45, -8,30,42,248,22,137,16,28,248,22,134,16,23,198,2,23,197,2,249,22,135, +86,23,201,1,28,248,22,174,15,23,196,2,86,94,23,196,1,248,80,144,45, +8,30,42,248,22,138,16,28,248,22,135,16,23,198,2,23,197,2,249,22,136, 16,23,199,2,248,80,144,49,8,29,42,23,205,2,28,249,22,169,9,248,22, 81,23,198,2,2,32,27,248,80,144,46,51,42,249,22,80,23,199,2,248,22, -191,16,247,22,143,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11,89, +128,17,247,22,144,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11,89, 146,41,39,11,249,80,144,49,57,42,248,22,102,23,201,2,11,27,28,248,22, -88,248,22,104,23,201,2,28,248,22,88,23,195,2,249,22,170,16,2,89,23, +88,248,22,104,23,201,2,28,248,22,88,23,195,2,249,22,171,16,2,89,23, 197,2,11,10,27,28,23,194,2,248,2,86,23,197,2,28,248,22,88,23,196, -2,2,39,28,249,22,170,16,2,89,23,198,2,248,2,86,23,197,2,249,22, +2,2,39,28,249,22,171,16,2,89,23,198,2,248,2,86,23,197,2,249,22, 176,7,23,198,2,2,40,27,28,23,195,1,86,94,23,197,1,249,22,94,28, 248,22,88,248,22,104,23,205,2,21,93,6,5,5,109,122,108,105,98,249,22, 1,22,94,249,22,2,80,144,56,8,31,42,248,22,104,23,208,2,23,198,1, 28,248,22,88,23,197,2,86,94,23,196,1,248,22,90,23,198,1,86,94,23, 197,1,23,196,1,252,80,144,55,8,23,42,23,207,1,248,22,81,23,199,2, -248,22,162,20,23,199,1,23,199,1,10,28,249,22,169,9,248,22,161,20,23, -198,2,2,37,248,80,144,45,8,30,42,248,22,137,16,249,22,135,16,248,22, -139,16,248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86,94, -28,28,248,22,173,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23,201, -2,250,22,178,11,69,114,101,113,117,105,114,101,249,22,137,8,6,17,17,98, +248,22,163,20,23,199,1,23,199,1,10,28,249,22,169,9,248,22,162,20,23, +198,2,2,37,248,80,144,45,8,30,42,248,22,138,16,249,22,136,16,248,22, +140,16,248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86,94, +28,28,248,22,174,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23,201, +2,250,22,179,11,69,114,101,113,117,105,114,101,249,22,137,8,6,17,17,98, 97,100,32,109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2,248, -22,81,23,199,2,6,0,0,23,204,2,250,22,180,11,2,22,2,33,23,198, -2,27,28,248,22,184,8,23,195,2,249,22,189,8,23,196,2,39,249,22,137, -16,248,22,138,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22,189, +22,81,23,199,2,6,0,0,23,204,2,250,22,181,11,2,22,2,33,23,198, +2,27,28,248,22,184,8,23,195,2,249,22,189,8,23,196,2,39,249,22,138, +16,248,22,139,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22,189, 8,23,197,2,40,248,80,144,47,8,24,42,23,195,2,90,144,42,11,89,146, 42,39,11,28,248,22,184,8,23,199,2,250,22,7,2,41,249,22,189,8,23, -203,2,41,2,41,248,22,130,16,23,198,2,86,95,23,195,1,23,193,1,27, +203,2,41,2,41,248,22,131,16,23,198,2,86,95,23,195,1,23,193,1,27, 28,248,22,184,8,23,200,2,249,22,189,8,23,201,2,42,249,80,144,52,61, 42,23,197,2,5,0,27,28,248,22,184,8,23,201,2,249,22,189,8,23,202, 2,43,248,22,152,5,23,200,2,27,250,22,158,2,80,144,55,44,41,248,22, -191,16,247,22,143,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27, +128,17,247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27, 249,22,80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,57,44, -41,248,22,191,16,247,22,143,14,195,192,27,28,23,204,2,248,22,152,5,249, +41,248,22,128,17,247,22,144,14,195,192,27,28,23,204,2,248,22,152,5,249, 22,80,248,22,153,5,23,200,2,23,207,2,23,196,2,86,95,28,23,212,2, 28,250,22,158,2,248,22,81,23,198,2,195,11,86,96,23,211,1,23,204,1, 23,194,1,12,27,251,22,31,11,80,144,59,53,41,9,28,248,22,15,80,144, -60,54,41,80,144,59,54,41,247,22,17,27,248,22,191,16,247,22,143,14,86, +60,54,41,80,144,59,54,41,247,22,17,27,248,22,128,17,247,22,144,14,86, 94,249,22,3,88,148,8,36,40,57,11,9,226,13,12,2,3,33,92,23,196, 2,248,28,248,22,15,80,144,58,54,41,32,0,88,148,39,40,45,11,9,222, 33,93,80,144,57,8,32,42,20,20,98,88,148,39,39,8,25,8,240,12,64, 0,0,9,233,18,21,14,15,12,11,7,6,4,1,2,33,95,23,195,1,23, 194,1,23,197,1,23,207,1,23,214,1,12,28,28,248,22,184,8,23,204,1, 86,94,23,212,1,11,28,23,212,1,28,248,22,153,7,23,206,2,10,28,248, -22,64,23,206,2,10,28,248,22,78,23,206,2,249,22,169,9,248,22,161,20, +22,64,23,206,2,10,28,248,22,78,23,206,2,249,22,169,9,248,22,162,20, 23,208,2,2,32,11,11,249,80,144,56,52,42,28,248,22,153,7,23,208,2, 249,22,80,23,209,1,248,80,144,59,8,29,42,23,215,1,86,94,23,212,1, -249,22,80,23,209,1,248,22,191,16,247,22,143,14,252,22,186,8,23,209,1, +249,22,80,23,209,1,248,22,128,17,247,22,144,14,252,22,186,8,23,209,1, 23,208,1,23,206,1,23,204,1,23,203,1,12,192,86,96,20,18,144,11,80, 143,39,59,248,80,144,40,8,27,40,249,22,31,11,80,144,42,41,40,248,22, -190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,142,15,80, +190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,143,15,80, 144,40,48,42,20,18,144,11,80,143,39,59,248,80,144,40,8,27,40,249,22, 31,11,80,144,42,41,40,20,18,144,11,80,143,39,59,248,80,144,40,8,27, 40,249,22,31,11,80,144,42,41,40,144,39,20,121,145,2,1,39,16,1,11, @@ -1543,7 +1543,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 9713); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,56,84,0,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,1,0,0,8,0, 18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0,135, 0,147,0,231,0,238,0,8,1,0,0,198,1,0,0,3,1,5,105,110,115, diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 34fda3ec84..0501a02a04 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -96,7 +96,9 @@ The third pass, called "optimize", performs constant propagation, constant folding, and function inlining; this pass mutates records - produced by the "letrec_check" pass. See "optimize.c". + produced by the "letrec_check" pass. See "optimize.c". This pass + isn't optional; for example, it calculates closure information that + the third pass uses. The fourth pass, called "resolve", finishes compilation by computing variable offsets and indirections (often mutating the records @@ -191,7 +193,8 @@ SHARED_OK int scheme_startup_use_jit = INIT_JIT_ON; void scheme_set_startup_use_jit(int v) { scheme_startup_use_jit = v; } -SHARED_OK static int valdiate_compile_result = 0; +SHARED_OK static int validate_compile_result = 0; +SHARED_OK static int recompile_every_compile = 0; /* THREAD LOCAL SHARED */ THREAD_LOCAL_DECL(volatile int scheme_fuel_counter); @@ -234,6 +237,7 @@ READ_ONLY static Scheme_Object *zero_rands_ptr; /* &zero_rands_ptr is dummy rand static Scheme_Object *eval(int argc, Scheme_Object *argv[]); static Scheme_Object *compile(int argc, Scheme_Object *argv[]); static Scheme_Object *compiled_p(int argc, Scheme_Object *argv[]); +static Scheme_Object *recompile(int argc, Scheme_Object *argv[]); static Scheme_Object *expand(int argc, Scheme_Object **argv); static Scheme_Object *local_expand(int argc, Scheme_Object **argv); static Scheme_Object *local_expand_expr(int argc, Scheme_Object **argv); @@ -259,6 +263,8 @@ static Scheme_Object *compile_module_constants(int argc, Scheme_Object **argv); static Scheme_Object *use_jit(int argc, Scheme_Object **argv); static Scheme_Object *disallow_inline(int argc, Scheme_Object **argv); +static Scheme_Object *recompile_top(Scheme_Object *top); + static Scheme_Object *_eval_compiled_multi_with_prompt(Scheme_Object *obj, Scheme_Env *env); void scheme_escape_to_continuation(Scheme_Object *obj, int num_rands, Scheme_Object **rands, Scheme_Object *alt_full); @@ -351,6 +357,7 @@ scheme_init_eval (Scheme_Env *env) GLOBAL_PRIM_W_ARITY2("eval-syntax", eval_stx, 1, 2, 0, -1, env); GLOBAL_PRIM_W_ARITY("compile", compile, 1, 1, env); + GLOBAL_PRIM_W_ARITY("compiled-expression-recompile", recompile, 1, 1, env); GLOBAL_PRIM_W_ARITY("compile-syntax", compile_stx, 1, 1, env); GLOBAL_PRIM_W_ARITY("compiled-expression?", compiled_p, 1, 1, env); GLOBAL_PRIM_W_ARITY("expand", expand, 1, 1, env); @@ -379,7 +386,24 @@ scheme_init_eval (Scheme_Env *env) /* Enables validation of bytecode as it is generated, to double-check that the compiler is producing valid bytecode as it should. */ - valdiate_compile_result = 1; + validate_compile_result = 1; + } + + { + /* Enables re-running the optimizer N times on every compilation. */ + const char *s; + s = getenv("PLT_RECOMPILE_COMPILE"); + if (s) { + int i = 0; + while ((s[i] >= '0') && (s[i] <= '9')) { + recompile_every_compile = (recompile_every_compile * 10) + (s[i]-'0'); + i++; + } + if (recompile_every_compile <= 0) + recompile_every_compile = 1; + else if (recompile_every_compile > 32) + recompile_every_compile = 32; + } } } @@ -3531,7 +3555,7 @@ scheme_do_eval(Scheme_Object *obj, int num_rands, Scheme_Object **rands, c = lv->count; i = lv->position; - ab = SCHEME_LET_AUTOBOX(lv); + ab = SCHEME_LET_VALUE_AUTOBOX(lv); value = lv->value; obj = lv->body; @@ -3593,7 +3617,7 @@ scheme_do_eval(Scheme_Object *obj, int num_rands, Scheme_Object **rands, PUSH_RUNSTACK(p, RUNSTACK, c); RUNSTACK_CHANGED(); - if (SCHEME_LET_AUTOBOX(lv)) { + if (SCHEME_LET_VOID_AUTOBOX(lv)) { GC_MAYBE_IGNORE_INTERIOR Scheme_Object **stack = RUNSTACK; UPDATE_THREAD_RSPTR_FOR_GC(); @@ -3991,6 +4015,48 @@ static int get_comp_flags(Scheme_Config *config) return comp_flags; } +static Scheme_Object *optimize_resolve_expr(Scheme_Object* o, Comp_Prefix *cp, Scheme_Object *src_insp_desc) +{ + Optimize_Info *oi; + Resolve_Prefix *rp; + Resolve_Info *ri; + Scheme_Compilation_Top *top; + /* TODO: see if this can be moved here completely */ + int comp_flags, enforce_consts, max_let_depth; + Scheme_Config *config; + + config = scheme_current_config(); + enforce_consts = SCHEME_TRUEP(scheme_get_param(config, MZCONFIG_COMPILE_MODULE_CONSTS)); + comp_flags = get_comp_flags(config); + if (enforce_consts) + comp_flags |= COMP_ENFORCE_CONSTS; + oi = scheme_optimize_info_create(cp, 1); + scheme_optimize_info_enforce_const(oi, enforce_consts); + if (!(comp_flags & COMP_CAN_INLINE)) + scheme_optimize_info_never_inline(oi); + o = scheme_optimize_expr(o, oi, 0); + + rp = scheme_resolve_prefix(0, cp, src_insp_desc); + ri = scheme_resolve_info_create(rp); + scheme_resolve_info_enforce_const(ri, enforce_consts); + scheme_enable_expression_resolve_lifts(ri); + + o = scheme_resolve_expr(o, ri); + max_let_depth = scheme_resolve_info_max_let_depth(ri); + o = scheme_sfs(o, NULL, max_let_depth); + + o = scheme_merge_expression_resolve_lifts(o, rp, ri); + + rp = scheme_remap_prefix(rp, ri); + + top = MALLOC_ONE_TAGGED(Scheme_Compilation_Top); + top->iso.so.type = scheme_compilation_top_type; + top->max_let_depth = max_let_depth; + top->code = o; + top->prefix = rp; + return (Scheme_Object *)top; +} + static void *compile_k(void) { Scheme_Thread *p = scheme_current_thread; @@ -4189,7 +4255,14 @@ static void *compile_k(void) top->code = o; top->prefix = rp; - if (valdiate_compile_result) { + if (recompile_every_compile) { + int i; + for (i = recompile_every_compile; i--; ) { + top = (Scheme_Compilation_Top *)recompile_top((Scheme_Object *)top); + } + } + + if (validate_compile_result) { scheme_validate_code(NULL, top->code, top->max_let_depth, top->prefix->num_toplevels, @@ -4810,6 +4883,39 @@ compiled_p(int argc, Scheme_Object *argv[]) : scheme_false); } +static Scheme_Object *recompile_top(Scheme_Object *top) +{ + Comp_Prefix *cp; + Scheme_Object *code; + +#if 0 + printf("Resolved Code:\n%s\n\n", scheme_print_to_string(((Scheme_Compilation_Top *)top)->code, NULL)); +#endif + + code = scheme_unresolve_top(top, &cp); + +#if 0 + printf("Unresolved Prefix:\n"); + printf("%s\n\n", scheme_print_to_string(cp, NULL)); + printf("Unresolved Code:\n"); + printf("%s\n\n", scheme_print_to_string(code, NULL)); +#endif + + top = optimize_resolve_expr(code, cp, ((Scheme_Compilation_Top*)top)->prefix->src_insp_desc); + + return top; +} + +static Scheme_Object * +recompile(int argc, Scheme_Object *argv[]) +{ + if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_compilation_top_type)) { + scheme_wrong_contract("compiled-expression-recompile", "compiled-expression?", 0, argc, argv); + } + + return recompile_top(argv[0]); +} + static Scheme_Object *expand(int argc, Scheme_Object **argv) { Scheme_Env *env; diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index ad314afbf4..4cb2bd4d67 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -719,7 +719,7 @@ int scheme_is_non_gc(Scheme_Object *obj, int depth) case scheme_let_value_type: if (depth) { Scheme_Let_Value *lv = (Scheme_Let_Value *)obj; - if (SCHEME_LET_AUTOBOX(lv)) + if (SCHEME_LET_VALUE_AUTOBOX(lv)) return 0; return scheme_is_non_gc(lv->body, depth - 1); } @@ -733,7 +733,7 @@ int scheme_is_non_gc(Scheme_Object *obj, int depth) case scheme_let_void_type: if (depth) { Scheme_Let_Void *lv = (Scheme_Let_Void *)obj; - if (SCHEME_LET_AUTOBOX(lv)) + if (SCHEME_LET_VOID_AUTOBOX(lv)) return 0; return scheme_is_non_gc(lv->body, depth - 1); } @@ -2721,7 +2721,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w case scheme_let_value_type: { Scheme_Let_Value *lv = (Scheme_Let_Value *)obj; - int ab = SCHEME_LET_AUTOBOX(lv), i, pos; + int ab = SCHEME_LET_VALUE_AUTOBOX(lv), i, pos; mz_jit_unbox_state ubs; START_JIT_DATA(); @@ -2829,7 +2829,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w scheme_stack_safety(jitter, c, 0); mz_runstack_pushed(jitter, c); - if (SCHEME_LET_AUTOBOX(lv)) { + if (SCHEME_LET_VOID_AUTOBOX(lv)) { int i; mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 1b5050e07d..1230849466 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -180,7 +180,7 @@ static Scheme_Object *write_let_value(Scheme_Object *obj) return cons(scheme_make_integer(lv->count), cons(scheme_make_integer(lv->position), - cons(SCHEME_LET_AUTOBOX(lv) ? scheme_true : scheme_false, + cons(SCHEME_LET_VALUE_AUTOBOX(lv) ? scheme_true : scheme_false, cons(scheme_protect_quote(lv->value), scheme_protect_quote(lv->body))))); } @@ -199,7 +199,7 @@ static Scheme_Object *read_let_value(Scheme_Object *obj) lv->position = SCHEME_INT_VAL(SCHEME_CAR(obj)); obj = SCHEME_CDR(obj); if (!SCHEME_PAIRP(obj)) return NULL; - SCHEME_LET_AUTOBOX(lv) = SCHEME_TRUEP(SCHEME_CAR(obj)); + SCHEME_LET_VALUE_AUTOBOX(lv) = SCHEME_TRUEP(SCHEME_CAR(obj)); obj = SCHEME_CDR(obj); if (!SCHEME_PAIRP(obj)) return NULL; lv->value = SCHEME_CAR(obj); @@ -215,7 +215,7 @@ static Scheme_Object *write_let_void(Scheme_Object *obj) lv = (Scheme_Let_Void *)obj; return cons(scheme_make_integer(lv->count), - cons(SCHEME_LET_AUTOBOX(lv) ? scheme_true : scheme_false, + cons(SCHEME_LET_VOID_AUTOBOX(lv) ? scheme_true : scheme_false, scheme_protect_quote(lv->body))); } @@ -230,7 +230,7 @@ static Scheme_Object *read_let_void(Scheme_Object *obj) lv->count = SCHEME_INT_VAL(SCHEME_CAR(obj)); obj = SCHEME_CDR(obj); if (!SCHEME_PAIRP(obj)) return NULL; - SCHEME_LET_AUTOBOX(lv) = SCHEME_TRUEP(SCHEME_CAR(obj)); + SCHEME_LET_VOID_AUTOBOX(lv) = SCHEME_TRUEP(SCHEME_CAR(obj)); lv->body = SCHEME_CDR(obj); return (Scheme_Object *)lv; diff --git a/racket/src/racket/src/mzmark_resolve.inc b/racket/src/racket/src/mzmark_resolve.inc index e537c20d21..45ad01b3b3 100644 --- a/racket/src/racket/src/mzmark_resolve.inc +++ b/racket/src/racket/src/mzmark_resolve.inc @@ -57,6 +57,12 @@ static int mark_unresolve_info_MARK(void *p, struct NewGC *gc) { gcMARK2(i->depths, gc); gcMARK2(i->prefix, gc); gcMARK2(i->closures, gc); + gcMARK2(i->closures, gc); + gcMARK2(i->module, gc); + gcMARK2(i->comp_prefix, gc); + gcMARK2(i->toplevels, gc); + gcMARK2(i->definitions, gc); + gcMARK2(i->ref_args, gc); return gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); @@ -69,6 +75,12 @@ static int mark_unresolve_info_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(i->depths, gc); gcFIXUP2(i->prefix, gc); gcFIXUP2(i->closures, gc); + gcFIXUP2(i->closures, gc); + gcFIXUP2(i->module, gc); + gcFIXUP2(i->comp_prefix, gc); + gcFIXUP2(i->toplevels, gc); + gcFIXUP2(i->definitions, gc); + gcFIXUP2(i->ref_args, gc); return gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index bcacc22f6a..c48bffab91 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -1309,6 +1309,12 @@ mark_unresolve_info { gcMARK2(i->depths, gc); gcMARK2(i->prefix, gc); gcMARK2(i->closures, gc); + gcMARK2(i->closures, gc); + gcMARK2(i->module, gc); + gcMARK2(i->comp_prefix, gc); + gcMARK2(i->toplevels, gc); + gcMARK2(i->definitions, gc); + gcMARK2(i->ref_args, gc); size: gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 20d4a1752b..5f8800a6ca 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -657,7 +657,7 @@ set_resolve(Scheme_Object *data, Resolve_Info *rslv) lv->count = 1; li = resolve_info_lookup(rslv, SCHEME_LOCAL_POS(var), &flags, NULL, 0); lv->position = li; - SCHEME_LET_AUTOBOX(lv) = (flags & SCHEME_INFO_BOXED); + SCHEME_LET_VALUE_AUTOBOX(lv) = (flags & SCHEME_INFO_BOXED); lv->value = val; if (!(flags & SCHEME_INFO_BOXED)) @@ -1562,7 +1562,7 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info) } else lv->position = 0; lv->count = clv->count; - SCHEME_LET_AUTOBOX(lv) = recbox; + SCHEME_LET_VALUE_AUTOBOX(lv) = recbox; for (j = lv->count; j--; ) { if (!recbox @@ -1661,7 +1661,7 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info) lvd->iso.so.type = scheme_let_void_type; lvd->body = first; lvd->count = cnt; - SCHEME_LET_AUTOBOX(lvd) = recbox; + SCHEME_LET_VOID_AUTOBOX(lvd) = recbox; first = (Scheme_Object *)lvd; } @@ -3197,7 +3197,7 @@ static int resolving_in_procedure(Resolve_Info *info) } /*========================================================================*/ -/* uresolve */ +/* unresolve */ /*========================================================================*/ #if 0 @@ -3206,6 +3206,12 @@ static int resolving_in_procedure(Resolve_Info *info) # define return_NULL return NULL #endif +#if 0 +# define LOG_UNRESOLVE(x) x +#else +# define LOG_UNRESOLVE(x) /* empty */ +#endif + typedef struct Unresolve_Info { MZTAG_IF_REQUIRED int stack_pos; /* stack in resolved coordinates */ @@ -3215,15 +3221,25 @@ typedef struct Unresolve_Info { mzshort *depths; Scheme_Prefix *prefix; Scheme_Hash_Table *closures; /* handle cycles */ - int has_non_leaf, body_size; + int has_non_leaf, has_tl, body_size; + + int inlining; + Scheme_Module *module; + Comp_Prefix *comp_prefix; + Scheme_Hash_Table *toplevels; + Scheme_Object *definitions; + mzshort *ref_args; } Unresolve_Info; static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int as_rator); +static Scheme_Object *unresolve_expr_2(Scheme_Object *e, Unresolve_Info *ui, int as_rator); +static Scheme_Sequence *unresolve_let_value(Scheme_Let_Value *lv, Unresolve_Info *ui, Scheme_Object* val, Scheme_Object *body); static Unresolve_Info *new_unresolve_info(Scheme_Prefix *prefix) { Unresolve_Info *ui; - int *f, *d; + int *f, *d, *r; + Scheme_Hash_Table *ht; ui = MALLOC_ONE_RT(Unresolve_Info); SET_REQUIRED_TAG(ui->type = scheme_rt_unresolve_info); @@ -3234,14 +3250,21 @@ static Unresolve_Info *new_unresolve_info(Scheme_Prefix *prefix) ui->flags = f; d = (mzshort *)scheme_malloc_atomic(sizeof(mzshort) * ui->stack_size); ui->depths = d; + r = (mzshort *)scheme_malloc_atomic(sizeof(mzshort) * ui->stack_size); + ui->ref_args = r; + + ui->inlining = 1; + ht = scheme_make_hash_table(SCHEME_hash_ptr); + ui->toplevels = ht; + ui->definitions = scheme_null; return ui; } -static int unresolve_stack_push(Unresolve_Info *ui, int n, int r_only) +static int unresolve_stack_push(Unresolve_Info *ui, int n, int r_only, int rev) { int pos, *f, i; - mzshort *d; + mzshort *d, *r; pos = ui->stack_pos; @@ -3252,19 +3275,32 @@ static int unresolve_stack_push(Unresolve_Info *ui, int n, int r_only) d = (mzshort *)scheme_malloc_atomic(sizeof(mzshort) * ((2 * ui->stack_size) + n)); memcpy(d, ui->depths, sizeof(mzshort) * pos); + r = (mzshort *)scheme_malloc_atomic(sizeof(mzshort) * ((2 * ui->stack_size) + n)); + memcpy(r, ui->ref_args, sizeof(mzshort) * pos); + ui->flags = f; ui->depths = d; + ui->ref_args = r; ui->stack_size = (2 * ui->stack_size) + n; } memset(ui->flags + pos, 0, sizeof(int) * n); if (!r_only) { - for (i = 0; i < n; i++) { - ui->depths[pos + i] = ui->depth++; + if (!rev) { + for (i = 0; i < n; i++) { + ui->depths[pos + i] = ui->depth++; + } + } else { + for (i = n; i--;) { + ui->depths[pos + i] = ui->depth++; + } } } ui->stack_pos += n; + + LOG_UNRESOLVE(printf("push %d(%d), d=%d, sp=%d, [%d, %d, %d, %d, %d]\n", n, r_only, ui->depth, ui->stack_pos, + ui->depths[0], ui->depths[1], ui->depths[2], ui->depths[3], ui->depths[4])); return pos; } @@ -3284,6 +3320,9 @@ static int *unresolve_stack_pop(Unresolve_Info *ui, int pos, int n) } else f = NULL; + LOG_UNRESOLVE(printf("pop %d(%d), d=%d, sp=%d, [%d, %d, %d, %d, %d]\n", n, pos, ui->depth, ui->stack_pos, + ui->depths[0], ui->depths[1], ui->depths[2], ui->depths[3], ui->depths[4])); + return f; } @@ -3331,11 +3370,1243 @@ static int unresolve_set_flag(Unresolve_Info *ui, int pos, int flag) old_flag = ui->flags[i]; flag = combine_flags(flag | (1 << SCHEME_USE_COUNT_SHIFT), old_flag); ui->flags[i] = flag; + + LOG_UNRESOLVE(printf("local %d -> %d (d=%d, sp=%d, i=%d, d[i]=%d)\n", + pos, ui->depth - ui->depths[i] - 1, ui->depth, ui->stack_pos, i, ui->depths[i])); return ui->depth - ui->depths[i] - 1; } -Scheme_Object *unresolve_closure(Scheme_Closure_Data *rdata, Unresolve_Info *ui) +static Scheme_Object *unresolve_closure_data_2(Scheme_Closure_Data *rdata, Unresolve_Info *ui) +{ + Scheme_Closure_Data *data; + Scheme_Object *body; + Closure_Info *cl; + int i, pos, data_pos, *flags, init_size, has_non_leaf, has_tl; + + scheme_delay_load_closure(rdata); + + data = MALLOC_ONE_TAGGED(Scheme_Closure_Data); + data->iso.so.type = scheme_compiled_unclosed_procedure_type; + + SCHEME_CLOSURE_DATA_FLAGS(data) = (SCHEME_CLOSURE_DATA_FLAGS(rdata) + & (CLOS_HAS_REST | CLOS_IS_METHOD)); + + + data->num_params = rdata->num_params; + data->name = rdata->name; + + pos = unresolve_stack_push(ui, data->num_params, 0, 0); + + + if (SCHEME_CLOSURE_DATA_FLAGS(rdata) & CLOS_HAS_TYPED_ARGS) { + for (i = 0; i < data->num_params; i++) { + LOG_UNRESOLVE(printf("ref_args[%d] = %d\n", ui->stack_pos - i, + scheme_boxmap_get(rdata->closure_map, i, rdata->closure_size))); + ui->ref_args[ui->stack_pos - i] = + scheme_boxmap_get(rdata->closure_map, i, rdata->closure_size); + } + } + + if (rdata->closure_size) { + data_pos = unresolve_stack_push(ui, rdata->closure_size, 1, 0); + /* remap closure slots: */ + /* TODO: remap ref-args? */ + for (i = rdata->closure_size; i--; ) { + int mp; + mp = ui->depths[pos - rdata->closure_map[i] - 1]; + ui->depths[ui->stack_pos - i - 1] = mp; + } + } else + data_pos = 0; + + init_size = ui->body_size; + has_non_leaf = ui->has_non_leaf; + ui->has_non_leaf = 0; + has_tl = ui->has_tl; + ui->has_tl = 0; + + body = unresolve_expr_2(rdata->code, ui, 0); + if (!body) return_NULL; + + data->code = body; + + cl = MALLOC_ONE_RT(Closure_Info); + SET_REQUIRED_TAG(cl->type = scheme_rt_closure_info); + data->closure_map = (mzshort *)cl; + + cl->body_size = (ui->body_size - init_size); + + cl->has_nonleaf = ui->has_non_leaf; + ui->has_non_leaf = has_non_leaf; + + cl->has_tl = ui->has_tl; + ui->has_tl = ui->has_tl || has_tl; + + if (rdata->closure_size) { + /* copy flags from unpacked closure to original slots */ + for (i = rdata->closure_size; i--; ) { + int a, b; + a = ui->flags[pos - rdata->closure_map[i] - 1]; + b = ui->flags[ui->stack_pos - i - 1]; + a = combine_flags(a, b); + ui->flags[pos - rdata->closure_map[i] - 1] = a; + } + (void)unresolve_stack_pop(ui, data_pos, 0); + } + + flags = unresolve_stack_pop(ui, pos, data->num_params); + cl->local_flags = flags; + + /* We don't need to set any more fields of cl, because + optimize does that. */ + + return (Scheme_Object *)data; +} + +static Scheme_Object *unresolve_expr_2_k(void) +{ + Scheme_Thread *p = scheme_current_thread; + Scheme_Object *e = (Scheme_Object *)p->ku.k.p1; + Unresolve_Info *ui = (Unresolve_Info *)p->ku.k.p2; + + p->ku.k.p1 = NULL; + p->ku.k.p2 = NULL; + + return unresolve_expr_2(e, ui, p->ku.k.i1); +} + +static void check_nonleaf_rator(Scheme_Object *rator, Unresolve_Info *ui) +{ + if (!scheme_check_leaf_rator(rator, NULL)) + ui->has_non_leaf = 1; +} + +static int unresolve_toplevel_pos(int pos, Unresolve_Info *ui) { + LOG_UNRESOLVE(printf("pos before = %d\n", pos)); + if (ui->module && + ui->module->prefix->num_stxes && + pos > (ui->module->prefix->num_toplevels + ui->module->prefix->num_stxes)) { + pos -= ui->module->prefix->num_stxes + 1; /* extra slot for lazy syntax */ + } + LOG_UNRESOLVE(printf("pos = %d\n", pos)); + + return pos; +} + +static Scheme_Object *unresolve_toplevel(Scheme_Object *rdata, Unresolve_Info *ui) { + Scheme_Object *v, *opos; + int pos; + pos = unresolve_toplevel_pos(SCHEME_TOPLEVEL_POS(rdata), ui); + opos = scheme_make_integer(pos); + v = scheme_hash_get(ui->toplevels, opos); + if (!v) { + v = scheme_make_toplevel(0, + pos, + 0, + SCHEME_TOPLEVEL_FLAGS(rdata) & SCHEME_TOPLEVEL_FLAGS_MASK); + scheme_hash_set(ui->toplevels, opos, v); + } + LOG_UNRESOLVE(printf("flags for %d: %d\n", pos, SCHEME_TOPLEVEL_FLAGS(rdata) & SCHEME_TOPLEVEL_FLAGS_MASK)); + + ui->has_tl = 1; + + return v; +} + +static Scheme_Object *unresolve_apply_values(Scheme_Object *e, Unresolve_Info *ui) { + Scheme_Object *o, *a, *b; + + a = SCHEME_PTR1_VAL(e); + a = unresolve_expr_2(a, ui, 0); + if (!a) return_NULL; + LOG_UNRESOLVE(printf("unresolve_apply_values: (a) %d %d\n", e->type, a->type)); + + b = SCHEME_PTR2_VAL(e); + b = unresolve_expr_2(b, ui, 0); + if (!b) return_NULL; + LOG_UNRESOLVE(printf(" (b) %d\n", b->type)); + + o = scheme_alloc_object(); + o->type = SCHEME_TYPE(e); + SCHEME_PTR1_VAL(o) = a; + SCHEME_PTR2_VAL(o) = b; + return o; +} + +static Scheme_Object *unresolve_define_values(Scheme_Object *e, Unresolve_Info *ui) { + Scheme_Object *vars = scheme_null; + Scheme_Object *vec, *val, *tl; + int i; + + LOG_UNRESOLVE(printf("define-values-size!!!: %d\n", (int)SCHEME_VEC_SIZE(e))); + for (i = SCHEME_VEC_SIZE(e); --i;) { + LOG_UNRESOLVE(printf("define-values: %d\n", SCHEME_TYPE(SCHEME_VEC_ELS(e)[i]))); + tl = unresolve_toplevel(SCHEME_VEC_ELS(e)[i], ui); + if (!tl) return_NULL; /* TODO: does this check need to be here? */ + vars = cons(tl, vars); + } + val = unresolve_expr_2(SCHEME_VEC_ELS(e)[0], ui, 0); + if (!val) return_NULL; + + vec = scheme_make_vector(2, NULL); + vec->type = scheme_define_values_type; + SCHEME_VEC_ELS(vec)[0] = vars; + SCHEME_VEC_ELS(vec)[1] = val; + return vec; +} + +static Scheme_Let_Header *make_let_header(int count) { + Scheme_Let_Header *lh; + lh = MALLOC_ONE_TAGGED(Scheme_Let_Header); + lh->iso.so.type = scheme_compiled_let_void_type; + lh->count = count; + lh->num_clauses = 0; + SCHEME_LET_FLAGS(lh) = SCHEME_LET_STAR; + return lh; +} + +static Scheme_Compiled_Let_Value *make_compiled_let_value(int position, int count) { + Scheme_Compiled_Let_Value *clv; + clv = MALLOC_ONE_TAGGED(Scheme_Compiled_Let_Value); + clv->iso.so.type = scheme_compiled_let_value_type; + clv->count = count; + clv->position = position; + return clv; +} + +typedef struct Unresolve_Let_Void_State { + /* All pointers so we can use scheme_malloc */ + Scheme_Let_Header *prev_head; + Scheme_Compiled_Let_Value *prev_let; + Scheme_Sequence *prev_seq; +} Unresolve_Let_Void_State; + +/* only one of lh, clv, seq, or body should be non-NULL */ +static void attach_lv(Scheme_Let_Header *lh, + Scheme_Compiled_Let_Value *clv, + Scheme_Sequence *seq, + Scheme_Object *body, + Unresolve_Let_Void_State *state) { + Scheme_Object *o; + o = lh ? (Scheme_Object *)lh : + (clv ? (Scheme_Object *)clv : + (seq ? (Scheme_Object *)seq : body)); + + if (state->prev_head) { + state->prev_head->body = o; + } else if (state->prev_let) { + state->prev_let->body = o; + } else if (state->prev_seq) { + state->prev_seq->array[state->prev_seq->count - 1] = o; + } + + state->prev_head = lh; + state->prev_let = clv; + state->prev_seq = seq; +} + +static Scheme_Object *unresolve_let_void(Scheme_Object *e, Unresolve_Info *ui) { + Scheme_Let_Void *lv = (Scheme_Let_Void *)e; + int i, pos, count, *flags; + Scheme_Let_Header *lh; + Scheme_Object *o; + Scheme_Compiled_Let_Value **clvmap; + Unresolve_Let_Void_State *state; + + state = scheme_malloc(sizeof(Unresolve_Let_Void_State)); + + count = lv->count; + pos = unresolve_stack_push(ui, count, 0, 0); + lh = make_let_header(count); + clvmap = MALLOC_N(Scheme_Compiled_Let_Value*, count); + + o = lv->body; + attach_lv(lh, NULL, NULL, NULL, state); + for (i = 0; i < count;) { + switch (SCHEME_TYPE(o)) { + case scheme_let_value_type: { + Scheme_Let_Value *lval = (Scheme_Let_Value *)o; + Scheme_Compiled_Let_Value *clv; + Scheme_Object *val; + clv = make_compiled_let_value(lval->position, lval->count); + lh->num_clauses++; + + if (SCHEME_LET_VALUE_AUTOBOX(lval)) { + SCHEME_LET_FLAGS(lh) = SCHEME_LET_RECURSIVE; + } + + val = unresolve_expr_2(lval->value, ui, 0); + if (!val) return_NULL; + clv->value = val; + + o = lval->body; + attach_lv(NULL, clv, NULL, NULL, state); + i += lval->count; + + break; + } + case scheme_boxenv_type: { + o = SCHEME_PTR2_VAL(o); + break; + } + case scheme_letrec_type: { + Scheme_Letrec *lr = (Scheme_Letrec *)o; + int j; + SCHEME_LET_FLAGS(lh) = SCHEME_LET_RECURSIVE; + for (j = 0; j < lr->count; j++) { + Scheme_Compiled_Let_Value *clv; + Scheme_Object *val; + clv = make_compiled_let_value(j, 1); + lh->num_clauses++; + val = unresolve_expr_2(lr->procs[j], ui, 0); + if (!val) return_NULL; + clv->value = val; + attach_lv(NULL, clv, NULL, NULL, state); + i++; + } + o = lr->body; + break; + } + case scheme_sequence_type: { + Scheme_Sequence *seq = (Scheme_Sequence *)o; + for (int i = 0; i < seq->count - 1; i++) { + if (!SAME_TYPE(SCHEME_TYPE(seq->array[i]), scheme_local_type)) { + scheme_signal_error("internal error: unexpected form in sequence: %d", SCHEME_TYPE(o)); + } + } + o = seq->array[seq->count - 1]; + break; + } + default: { + scheme_signal_error("internal error: unexpected form in let-void: %d", SCHEME_TYPE(o)); + } + } + } + + o = unresolve_expr_2(o, ui, 0); + if (!o) return_NULL; + attach_lv(NULL, NULL, NULL, o, state); + + flags = unresolve_stack_pop(ui, pos, lv->count); + + /* Set up flags */ + { + Scheme_Compiled_Let_Value *clv; + int count = 0, *clv_flags; + clv = (Scheme_Compiled_Let_Value *)(lh->body); + while (count < lv->count) { + if (SAME_TYPE(SCHEME_TYPE((Scheme_Object *)clv), scheme_sequence_type)) { + Scheme_Sequence *seq = (Scheme_Sequence *)clv; + clv = (Scheme_Compiled_Let_Value *)seq->array[seq->count - 1]; + } + clv_flags = (int *)scheme_malloc_atomic(sizeof(int) * clv->count); + for (i = 0; i < clv->count; i++) { + clv_flags[i] = flags[i + count]; + } + clv->flags = clv_flags; + count += clv->count; + clv = (Scheme_Compiled_Let_Value *)(clv->body); + } + } + + return (Scheme_Object *)lh; +} + + +static Scheme_Object *unresolve_prefix_symbol(Scheme_Object *s, Unresolve_Info *ui) { + Module_Variable *mv; + + mv = MALLOC_ONE_TAGGED(Module_Variable); + mv->iso.so.type = scheme_module_variable_type; + + mv->modidx = ui->module->self_modidx; + mv->sym = s; + mv->insp = ui->module->insp; + mv->pos = -1; + mv->mod_phase = 0; + SCHEME_MODVAR_FLAGS(mv) |= SCHEME_MODVAR_FIXED; + return (Scheme_Object *)mv; +} + +static Scheme_Object *unresolve_closure(Scheme_Object *e, Unresolve_Info *ui) { + + Scheme_Object *r, *c; + int stack_pos, depth; + + c = scheme_hash_get(ui->closures, e); + + if (c && SAME_TYPE(SCHEME_TYPE(c), scheme_compiled_toplevel_type)) { + return c; + } + + stack_pos = ui->stack_pos; + depth = ui->depth; + + r = unresolve_closure_data_2(SCHEME_COMPILED_CLOS_CODE(e), ui); + return r; +} + +static Comp_Prefix *unresolve_prefix(Resolve_Prefix *rp, Unresolve_Info *ui) { + Comp_Prefix *cp; + Scheme_Object *o; + int i; + cp = MALLOC_ONE_TAGGED(Comp_Prefix); +#ifdef MZTAG_REQUIRED + cp->type = scheme_rt_comp_prefix; +#endif + cp->num_toplevels = 0; + cp->toplevels = NULL; + for (i = 0; i < rp->num_toplevels; i++) { + if (SCHEME_SYMBOLP(rp->toplevels[i])) { + Scheme_Object *mv; + mv = unresolve_prefix_symbol(rp->toplevels[i], ui); + o = scheme_register_toplevel_in_comp_prefix(mv, cp, 0, NULL); + } else { + o = scheme_register_toplevel_in_comp_prefix(rp->toplevels[i], cp, 0, NULL); + } + scheme_hash_set(ui->toplevels, scheme_make_integer(SCHEME_TOPLEVEL_POS(o)), o); + } + for (i = 0; i < rp->num_lifts; i++) { + Scheme_Object *mv, *sym; + sym = scheme_make_symbol("lift"); + sym = scheme_gensym(sym); + mv = unresolve_prefix_symbol(sym, ui); + o = scheme_register_toplevel_in_comp_prefix(mv, cp, 0, NULL); + scheme_hash_set(ui->toplevels, scheme_make_integer(SCHEME_TOPLEVEL_POS(o)), o); + } + cp->stxes = NULL; + for (i = 0; i < rp->num_stxes; i++) { + if (rp->stxes[i]) { + scheme_register_stx_in_comp_prefix(rp->stxes[i], cp); + } else { + cp->num_stxes++; + } + } + cp->inline_variants = NULL; + cp->unbound = NULL; + return cp; +} + +void locate_cyclic_closures(Scheme_Object *e, Unresolve_Info *ui) { + switch(SCHEME_TYPE(e)) { + case scheme_sequence_type: + case scheme_begin0_sequence_type: + case scheme_splice_sequence_type: + { + Scheme_Sequence *seq = (Scheme_Sequence *)e; + for (int i = 0; i < seq->count; i++) { + locate_cyclic_closures(seq->array[i], ui); + } + } + break; + case scheme_application_type: + { + Scheme_App_Rec *app = (Scheme_App_Rec *)e; + for (int i = 0; i < app->num_args + 1; i++) { + locate_cyclic_closures(app->args[i], ui); + } + } + break; + case scheme_application2_type: + { + Scheme_App2_Rec *app = (Scheme_App2_Rec *)e; + locate_cyclic_closures(app->rator, ui); + locate_cyclic_closures(app->rand, ui); + } + break; + case scheme_application3_type: + { + Scheme_App3_Rec *app = (Scheme_App3_Rec *)e; + locate_cyclic_closures(app->rator, ui); + locate_cyclic_closures(app->rand1, ui); + locate_cyclic_closures(app->rand2, ui); + } + break; + case scheme_branch_type: + { + Scheme_Branch_Rec *b = (Scheme_Branch_Rec *)e; + locate_cyclic_closures(b->test, ui); + locate_cyclic_closures(b->tbranch, ui); + locate_cyclic_closures(b->fbranch, ui); + } + break; + case scheme_with_cont_mark_type: + case scheme_with_immed_mark_type: + { + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)e; + locate_cyclic_closures(wcm->key, ui); + locate_cyclic_closures(wcm->val, ui); + locate_cyclic_closures(wcm->body, ui); + } + break; + case scheme_let_void_type: + { + Scheme_Let_Void *lv = (Scheme_Let_Void *)e; + locate_cyclic_closures(lv->body, ui); + } + break; + case scheme_letrec_type: + { + Scheme_Letrec *lr = (Scheme_Letrec *)e; + for (int i = 0; i < lr->count; i++) { + locate_cyclic_closures(lr->procs[i], ui); + } + locate_cyclic_closures(lr->body, ui); + } + break; + case scheme_let_one_type: + { + Scheme_Let_One *lo = (Scheme_Let_One *)e; + locate_cyclic_closures(lo->value, ui); + locate_cyclic_closures(lo->body, ui); + } + break; + case scheme_closure_type: + { + Scheme_Object *c; + c = scheme_hash_get(ui->closures, e); + + if (SAME_OBJ(c, scheme_true)) { + Scheme_Object *s, *mv, *tl; + s = scheme_make_symbol("cyclic"); + s = scheme_gensym(s); + mv = unresolve_prefix_symbol(s, ui); + tl = scheme_register_toplevel_in_comp_prefix(mv, ui->comp_prefix, 0, NULL); + scheme_hash_set(ui->closures, e, tl); + } else if (c) { + /* do nothing */ + } else { + Scheme_Closure *cl = (Scheme_Closure *)e; + scheme_hash_set(ui->closures, e, scheme_true); + locate_cyclic_closures((Scheme_Object *)cl->code, ui); + } + } + break; + case scheme_unclosed_procedure_type: + { + Scheme_Closure_Data *cd = (Scheme_Closure_Data *)e; + locate_cyclic_closures(cd->code, ui); + } + break; + case scheme_inline_variant_type: + { + Scheme_Object *a; + a = SCHEME_VEC_ELS(e)[0]; + locate_cyclic_closures(a, ui); + } + break; + case scheme_define_values_type: + { + /* TODO: are the rest all toplevels? */ + locate_cyclic_closures(SCHEME_VEC_ELS(e)[0], ui); + } + break; + case scheme_set_bang_type: + { + Scheme_Set_Bang *sb = (Scheme_Set_Bang *)e; + locate_cyclic_closures(sb->var, ui); + locate_cyclic_closures(sb->val, ui); + } + break; + case scheme_varref_form_type: + case scheme_apply_values_type: + { + Scheme_Object *a, *b; + a = SCHEME_PTR1_VAL(e); + locate_cyclic_closures(a, ui); + b = SCHEME_PTR2_VAL(e); + locate_cyclic_closures(b, ui); + } + break; + case scheme_boxenv_type: + { + locate_cyclic_closures(SCHEME_PTR2_VAL(e), ui); + } + break; + case scheme_case_lambda_sequence_type: + { + Scheme_Case_Lambda *cl = (Scheme_Case_Lambda *)e; + for (int i = 0; i < cl->count; i++) { + locate_cyclic_closures(cl->array[i], ui); + } + } + break; + case scheme_let_value_type: + { + Scheme_Let_Value *lv = (Scheme_Let_Value *)e; + locate_cyclic_closures(lv->value, ui); + locate_cyclic_closures(lv->body, ui); + } + break; + default: + break; + } +} + +Scheme_Object *unresolve_module(Scheme_Object *e, Unresolve_Info *ui) +{ + Scheme_Module *m = (Scheme_Module *)e, *nm; + Scheme_Object *dummy, *bs, *bs2, *ds, **bss; + Scheme_Hash_Table *ht; + Comp_Prefix *cp; + int i, cnt, len; + + ui->module = m; + cp = unresolve_prefix(m->prefix, ui); + if (!cp) return_NULL; + ui->comp_prefix = cp; + + cnt = SCHEME_VEC_SIZE(m->bodies[0]); + bs = scheme_make_vector(cnt, NULL); + + ht = scheme_make_hash_table(SCHEME_hash_ptr); + ui->closures = ht; + for (i = 0; i < cnt; i++) { + locate_cyclic_closures(SCHEME_VEC_ELS(m->bodies[0])[i], ui); + } + + len = 0; + for (i = 0; i < ui->closures->size; i++) { + if (ui->closures->vals[i] && + SAME_TYPE(SCHEME_TYPE(ui->closures->vals[i]), scheme_compiled_toplevel_type)) { + Scheme_Object *d, *vars, *val; + len++; + d = scheme_make_vector(2, NULL); + d->type = scheme_define_values_type; + vars = cons(ui->closures->vals[i], scheme_null); + val = unresolve_closure_data_2(SCHEME_COMPILED_CLOS_CODE(ui->closures->keys[i]), ui); + SCHEME_VEC_ELS(d)[0] = vars; + SCHEME_VEC_ELS(d)[1] = val; + d = cons(d, ui->definitions); + ui->definitions = d; + } + } + + for (i = 0; i < cnt; i++) { + Scheme_Object *b; + b = unresolve_expr_2(SCHEME_VEC_ELS(m->bodies[0])[i], ui, 0); + if (!b) return_NULL; + SCHEME_VEC_ELS(bs)[i] = b; + } + len = scheme_list_length(ui->definitions); + ds = ui->definitions; + bs2 = scheme_make_vector(cnt + len, NULL); + for (i = 0; SCHEME_PAIRP(ds); ds = SCHEME_CDR(ds), i++) { + SCHEME_VEC_ELS(bs2)[i] = SCHEME_CAR(ds); + } + for (i = 0; i < cnt; i++) { + SCHEME_VEC_ELS(bs2)[i + len] = SCHEME_VEC_ELS(bs)[i]; + } + + dummy = scheme_make_toplevel(0, SCHEME_TOPLEVEL_POS(m->dummy), 0, 0); + + nm = MALLOC_ONE_TAGGED(Scheme_Module); + nm->so.type = scheme_module_type; + nm->predefined = m->predefined; + + nm->modname = m->modname; + nm->modsrc = m->modsrc; + + nm->et_requires = m->et_requires; + nm->requires = m->requires; + nm->tt_requires = m->tt_requires; + nm->dt_requires = m->dt_requires; + nm->other_requires = m->other_requires; + + bss = MALLOC_N(Scheme_Object*, m->num_phases); + nm->bodies = bss; + nm->bodies[0] = bs2; + /* Other phases are left as-is (and resolve doesn't traverse them): */ + for (i = 1; i < m->num_phases; i++) { + nm->bodies[i] = m->bodies[i]; + } + + nm->me = m->me; + + nm->num_phases = m->num_phases; + + nm->exp_infos = m->exp_infos; + + nm->self_modidx = m->self_modidx; + nm->insp = m->insp; + + nm->lang_info = m->lang_info; + + nm->comp_prefix = cp; + nm->max_let_depth = 0; + nm->prefix = NULL; + nm->dummy = dummy; + nm->rn_stx = m->rn_stx; + + /* leave submodules alone (and resolve doesn't traverse them): */ + nm->submodule_path = m->submodule_path; + nm->pre_submodules = m->pre_submodules; + nm->post_submodules = m->post_submodules; + nm->pre_submodule_names = m->pre_submodule_names; + nm->submodule_ancestry = m->submodule_ancestry; + /* the `supermodule` field is only for instantiated modules */ + + ui->module = NULL; + ui->comp_prefix = NULL; + + return (Scheme_Object *)nm; +} + +static Scheme_Sequence *unresolve_let_value(Scheme_Let_Value *lv, Unresolve_Info *ui, + Scheme_Object* val, Scheme_Object *body) { + Scheme_Set_Bang *sb; + Scheme_Object *var; + Scheme_Sequence *seq; + + LOG_UNRESOLVE(printf("set! position: %d (stack pos %d)\n", lv->position, ui->stack_pos)); + if (ui->ref_args[ui->stack_pos - lv->position]) { + Scheme_App2_Rec *app2; + var = scheme_make_local(scheme_local_type, + unresolve_set_flag(ui, + lv->position, + SCHEME_WAS_USED), + 0); + app2 = MALLOC_ONE_TAGGED(Scheme_App2_Rec); + app2->iso.so.type = scheme_application2_type; + app2->rator = var; + app2->rand = val; + seq = scheme_malloc_sequence(2); + seq->so.type = scheme_sequence_type; + seq->count = 2; + seq->array[0] = (Scheme_Object *)app2; + seq->array[1] = body; + return seq; + } + var = scheme_make_local(scheme_local_type, + unresolve_set_flag(ui, + lv->position, + (SCHEME_WAS_SET_BANGED | SCHEME_WAS_USED)), + 0); + + + sb = MALLOC_ONE_TAGGED(Scheme_Set_Bang); + sb->so.type = scheme_set_bang_type; + sb->var = var; + sb->val = val; + + seq = scheme_malloc_sequence(2); + seq->so.type = scheme_sequence_type; + seq->count = 2; + seq->array[0] = (Scheme_Object *)sb; + seq->array[1] = body; + return seq; +} + +Scheme_App_Rec *maybe_unresolve_app_refs(Scheme_App_Rec *app, Unresolve_Info *ui) { + Scheme_Object *rator; + rator = app->args[0]; + + /* TODO: check if in ui->closures */ + if (SAME_TYPE(SCHEME_TYPE(rator), scheme_closure_type) && + (SCHEME_CLOSURE_DATA_FLAGS((SCHEME_COMPILED_CLOS_CODE(rator))) & CLOS_HAS_TYPED_ARGS)) { + Scheme_Closure_Data *data = SCHEME_COMPILED_CLOS_CODE(rator); + Scheme_App_Rec *new_app; + Scheme_Object *new_rator; + int i; + + new_app = scheme_malloc_application(app->num_args + 1); + + LOG_UNRESOLVE(printf("REF app\n")); + for(i = 0; i < data->num_params; i++) { + LOG_UNRESOLVE(printf("%d: %d\n", i, scheme_boxmap_get(data->closure_map, i, data->closure_size))); + LOG_UNRESOLVE(printf("ui->stack_pos = %d, argpos = %d, i = %d\n", ui->stack_pos, SCHEME_LOCAL_POS(app->args[i + 1]), i)); + if ((scheme_boxmap_get(data->closure_map, i, data->closure_size) & CLOS_TYPE_BOXED) && + SAME_TYPE(SCHEME_TYPE(app->args[i + 1]), scheme_local_type) && + !ui->ref_args[ui->stack_pos - SCHEME_LOCAL_POS(app->args[i + 1])]) { + Scheme_Case_Lambda *cl; + Scheme_Closure_Data *d0, *d1; + Scheme_Set_Bang *sb; + Scheme_Object *local; + Scheme_Object *arg, *s; + int *flags; + Closure_Info *ci; + LOG_UNRESOLVE(printf("This will be a case-lambda: %d\n", i)); + + + cl = (Scheme_Case_Lambda *)scheme_malloc_tagged(sizeof(Scheme_Case_Lambda) + + ((2 - mzFLEX_DELTA) * sizeof(Scheme_Object *))); + + cl->so.type = scheme_case_lambda_sequence_type; + cl->count = 2; + s = scheme_make_symbol("cl"); + s = scheme_gensym(s); + cl->name = s; + + arg = scheme_make_local(scheme_local_type, + unresolve_set_flag(ui, + SCHEME_LOCAL_POS(app->args[i + 1]), + (SCHEME_WAS_SET_BANGED | SCHEME_WAS_USED)), + 0); + + d0 = MALLOC_ONE_TAGGED(Scheme_Closure_Data); + d0->iso.so.type = scheme_compiled_unclosed_procedure_type; + d0->num_params = 0; + d0->code = arg; + ci = MALLOC_ONE_RT(Closure_Info); + SET_REQUIRED_TAG(ci->type = scheme_rt_closure_info); + d0->closure_map = (mzshort *)ci; + s = scheme_make_symbol("d0"); + s = scheme_gensym(s); + d0->name = s; + cl->array[0] = (Scheme_Object *)d0; + + + d1 = MALLOC_ONE_TAGGED(Scheme_Closure_Data); + d1->iso.so.type = scheme_compiled_unclosed_procedure_type; + d1->num_params = 1; + + sb = MALLOC_ONE_TAGGED(Scheme_Set_Bang); + sb->so.type = scheme_set_bang_type; + local = scheme_make_local(scheme_local_type, SCHEME_LOCAL_POS(arg) + 1, 0); + sb->var = local; + local = scheme_make_local(scheme_local_type, 0, 0); + sb->val = local; + d1->code = (Scheme_Object *)sb; + ci = MALLOC_ONE_RT(Closure_Info); + SET_REQUIRED_TAG(ci->type = scheme_rt_closure_info); + flags = (int *)scheme_malloc_atomic(sizeof(int)); + flags[0] = SCHEME_WAS_USED; + ci->local_flags = flags; + d1->closure_map = (mzshort *)ci; + + + s = scheme_make_symbol("d1"); + s = scheme_gensym(s); + d1->name = s; + cl->array[1] = (Scheme_Object *)d1; + + new_app->args[i + 1] = (Scheme_Object *)cl; + } else { + Scheme_Object *arg; + arg = unresolve_expr_2(app->args[i + 1], ui, 0); + new_app->args[i + 1] = arg; + } + } + new_rator = unresolve_expr_2(rator, ui, 0); + new_app->args[0] = new_rator; + + return new_app; + } + return_NULL; +} + + +static Scheme_Object *unresolve_expr_2(Scheme_Object *e, Unresolve_Info *ui, int as_rator) +{ +#ifdef DO_STACK_CHECK + { +# include "mzstkchk.h" + { + Scheme_Thread *p = scheme_current_thread; + + p->ku.k.p1 = (void *)e; + p->ku.k.p2 = (void *)ui; + p->ku.k.i1 = as_rator; + + return scheme_handle_stack_overflow(unresolve_expr_2_k); + } + } +#endif + + ui->body_size++; + + switch (SCHEME_TYPE(e)) { + case scheme_local_type: + return scheme_make_local(scheme_local_type, + unresolve_set_flag(ui, + SCHEME_LOCAL_POS(e), + (SCHEME_WAS_USED + | (as_rator + ? SCHEME_WAS_ONLY_APPLIED + : 0))), + 0); + case scheme_local_unbox_type: + { + if (ui->ref_args[ui->stack_pos - SCHEME_LOCAL_POS(e)]) { + Scheme_App_Rec *app; + Scheme_Object *rator; + LOG_UNRESOLVE(printf("local unbox: %d (stack pos %d)\n", SCHEME_LOCAL_POS(e), ui->stack_pos)); + app = scheme_malloc_application(1); + rator = scheme_make_local(scheme_local_type, + unresolve_set_flag(ui, SCHEME_LOCAL_POS(e), SCHEME_WAS_USED), + 0); + app->args[0] = rator; + return (Scheme_Object *)app; + } + return scheme_make_local(scheme_local_type, + unresolve_set_flag(ui, SCHEME_LOCAL_POS(e), + (SCHEME_WAS_SET_BANGED | SCHEME_WAS_USED)), + 0); + } + case scheme_sequence_type: + case scheme_begin0_sequence_type: + case scheme_splice_sequence_type: + { + Scheme_Sequence *seq = (Scheme_Sequence *)e, *seq2; + int i; + + seq2 = scheme_malloc_sequence(seq->count); + seq2->so.type = seq->so.type; + seq2->count = seq->count; + for (i = seq->count; i--; ) { + e = unresolve_expr_2(seq->array[i], ui, 0); + if (!e) return_NULL; + seq2->array[i] = e; + } + + return (Scheme_Object *)seq2; + } + break; + case scheme_application_type: + { + Scheme_App_Rec *app = (Scheme_App_Rec *)e, *app2; + Scheme_Object *a; + int pos, i; + + ui->body_size += app->num_args; + check_nonleaf_rator(app->args[0], ui); + + pos = unresolve_stack_push(ui, app->num_args, 1, 0); + + app2 = maybe_unresolve_app_refs(app, ui); + if (app2) { + (void)unresolve_stack_pop(ui, pos, 0); + return (Scheme_Object *)app2; + } + + app2 = scheme_malloc_application(app->num_args+1); + + for (i = app->num_args + 1; i--; ) { + a = unresolve_expr_2(app->args[i], ui, 0); + if (!a) return_NULL; + app2->args[i] = a; + } + + (void)unresolve_stack_pop(ui, pos, 0); + + return (Scheme_Object *)app2; + } + case scheme_application2_type: + { + Scheme_App2_Rec *app = (Scheme_App2_Rec *)e, *app2; + Scheme_Object *rator, *rand; + int pos; + + ui->body_size += 1; + check_nonleaf_rator(app->rator, ui); + + pos = unresolve_stack_push(ui, 1, 1, 0); + + rator = unresolve_expr_2(app->rator, ui, 0); + if (!rator) return_NULL; + rand = unresolve_expr_2(app->rand, ui, 0); + if (!rand) return_NULL; + + (void)unresolve_stack_pop(ui, pos, 0); + + app2 = MALLOC_ONE_TAGGED(Scheme_App2_Rec); + app2->iso.so.type = scheme_application2_type; + app2->rator = rator; + app2->rand = rand; + + return (Scheme_Object *)app2; + } + case scheme_application3_type: + { + Scheme_App3_Rec *app = (Scheme_App3_Rec *)e, *app2; + Scheme_Object *rator, *rand1, *rand2; + int pos; + + ui->body_size += 2; + check_nonleaf_rator(app->rator, ui); + + pos = unresolve_stack_push(ui, 2, 1, 0); + + rator = unresolve_expr_2(app->rator, ui, 0); + if (!rator) return_NULL; + rand1 = unresolve_expr_2(app->rand1, ui, 0); + if (!rand1) return_NULL; + rand2 = unresolve_expr_2(app->rand2, ui, 0); + if (!rand2) return_NULL; + + (void)unresolve_stack_pop(ui, pos, 0); + + app2 = MALLOC_ONE_TAGGED(Scheme_App3_Rec); + app2->iso.so.type = scheme_application3_type; + app2->rator = rator; + app2->rand1 = rand1; + app2->rand2 = rand2; + + return (Scheme_Object *)app2; + } + case scheme_branch_type: + { + Scheme_Branch_Rec *b = (Scheme_Branch_Rec *)e, *b2; + Scheme_Object *tst, *thn, *els; + + tst = unresolve_expr_2(b->test, ui, 0); + if (!tst) return_NULL; + thn = unresolve_expr_2(b->tbranch, ui, 0); + if (!thn) return_NULL; + els = unresolve_expr_2(b->fbranch, ui, 0); + if (!els) return_NULL; + + b2 = MALLOC_ONE_TAGGED(Scheme_Branch_Rec); + b2->so.type = scheme_branch_type; + b2->test = tst; + b2->tbranch = thn; + b2->fbranch = els; + + return (Scheme_Object *)b2; + } + case scheme_with_cont_mark_type: + { + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)e, *wcm2; + Scheme_Object *k, *v, *b; + + k = unresolve_expr_2(wcm->key, ui, 0); + if (!k) return_NULL; + v = unresolve_expr_2(wcm->val, ui, 0); + if (!v) return_NULL; + b = unresolve_expr_2(wcm->body, ui, 0); + if (!b) return_NULL; + + wcm2 = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); + wcm2->so.type = scheme_with_cont_mark_type; + wcm2->key = k; + wcm2->val = v; + wcm2->body = b; + + return (Scheme_Object *)wcm2; + } + case scheme_with_immed_mark_type: + { + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)e, *wcm2; + Scheme_Object *k, *v, *b; + int *flags, pos; + + k = unresolve_expr_2(wcm->key, ui, 0); + if (!k) return_NULL; + v = unresolve_expr_2(wcm->val, ui, 0); + if (!v) return_NULL; + + pos = unresolve_stack_push(ui, 1, 0, 0); + b = unresolve_expr_2(wcm->body, ui, 0); + if (!b) return_NULL; + flags = unresolve_stack_pop(ui, pos, 1); + + wcm2 = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); + wcm2->so.type = scheme_with_immed_mark_type; + wcm2->key = k; + wcm2->val = v; + wcm2->body = b; + + return (Scheme_Object *)wcm2; + } + case scheme_let_void_type: + { + return unresolve_let_void(e, ui); + } + case scheme_let_one_type: + { + Scheme_Let_One *lo = (Scheme_Let_One *)e; + Scheme_Object *rhs, *body; + Scheme_Let_Header *lh; + Scheme_Compiled_Let_Value *clv; + int *flags, pos; + + pos = unresolve_stack_push(ui, 1, 1 /* => post-bind RHS */, 0); + rhs = unresolve_expr_2(lo->value, ui, 0); + if (!rhs) return_NULL; + (void)unresolve_stack_pop(ui, pos, 0); + + pos = unresolve_stack_push(ui, 1, 0, 0); + body = unresolve_expr_2(lo->body, ui, 0); + if (!body) return_NULL; + flags = unresolve_stack_pop(ui, pos, 1); + + lh = MALLOC_ONE_TAGGED(Scheme_Let_Header); + lh->iso.so.type = scheme_compiled_let_void_type; + lh->count = 1; + lh->num_clauses = 1; + + clv = MALLOC_ONE_TAGGED(Scheme_Compiled_Let_Value); + clv->iso.so.type = scheme_compiled_let_value_type; + clv->count = 1; + clv->position = 0; + clv->value = rhs; + clv->flags = flags; + clv->body = body; + + lh->body = (Scheme_Object *)clv; + + return (Scheme_Object *)lh; + } + case scheme_closure_type: + { + return unresolve_closure(e, ui); + } + case scheme_unclosed_procedure_type: + { + return unresolve_closure_data_2((Scheme_Closure_Data *)e, ui); + } + case scheme_inline_variant_type: + { + Scheme_Object *a; + a = SCHEME_VEC_ELS(e)[0]; + a = unresolve_expr_2(a, ui, 0); + if (!a) return_NULL; + return a; + } + case scheme_module_type: + { + return unresolve_module(e, ui); + } + case scheme_define_values_type: + { + return unresolve_define_values(e, ui); + } + case scheme_set_bang_type: + { + Scheme_Set_Bang *sb = (Scheme_Set_Bang *)e, *sb2; + Scheme_Object *var, *val; + var = unresolve_expr_2(sb->var, ui, 0); + if (!var) return_NULL; + if (SAME_TYPE(SCHEME_TYPE(var), scheme_compiled_toplevel_type)) { + SCHEME_TOPLEVEL_FLAGS(var) |= SCHEME_TOPLEVEL_MUTATED; + } + val = unresolve_expr_2(sb->val, ui, 0); + if (!val) return_NULL; + + LOG_UNRESOLVE(printf("SET BANG: %d, %d\n", SCHEME_TYPE(val), SCHEME_TYPE(var))); + + sb2 = MALLOC_ONE_TAGGED(Scheme_Set_Bang); + sb2->so.type = scheme_set_bang_type; + sb2->var = var; + sb2->val = val; + return (Scheme_Object *)sb2; + } + case scheme_varref_form_type: + { + Scheme_Object *a, *b, *o; + a = SCHEME_PTR1_VAL(e); + a = unresolve_expr_2(a, ui, 0); + if (!a) return_NULL; + LOG_UNRESOLVE(printf("unresolve_varref: (a) %d %d\n", e->type, a->type)); + + if (SAME_TYPE(SCHEME_TYPE(a), scheme_compiled_toplevel_type)) { + SCHEME_TOPLEVEL_FLAGS(a) |= SCHEME_TOPLEVEL_MUTATED; + } + + b = SCHEME_PTR2_VAL(e); + b = unresolve_expr_2(b, ui, 0); + if (!b) return_NULL; + LOG_UNRESOLVE(printf(" (b) %d\n", b->type)); + + o = scheme_alloc_object(); + o->type = scheme_varref_form_type; + SCHEME_PTR1_VAL(o) = a; + SCHEME_PTR2_VAL(o) = b; + return o; + } + case scheme_apply_values_type: + { + return unresolve_apply_values(e, ui); + } + case scheme_boxenv_type: /* TODO make sure this is okay */ + { + return unresolve_expr_2(SCHEME_PTR2_VAL(e), ui, 0); + } + case scheme_toplevel_type: + { + e = unresolve_toplevel(e, ui); + return e; + } + case scheme_case_lambda_sequence_type: + { + int i, cnt; + Scheme_Case_Lambda *cl = (Scheme_Case_Lambda *)e, *cl2; + + cl2 = (Scheme_Case_Lambda *)scheme_malloc_tagged(sizeof(Scheme_Case_Lambda) + + ((cl->count - mzFLEX_DELTA) * sizeof(Scheme_Object*))); + cl2->so.type = scheme_case_lambda_sequence_type; + cl2->count = cl->count; + cl2->name = cl->name; /* this may need more handling, see schpriv.c:1456 */ + + cnt = cl->count; + + for (i = 0; i < cnt; i++) { + Scheme_Object *le; + Scheme_Closure_Data *data; + if (SAME_TYPE(SCHEME_TYPE(cl->array[i]), scheme_closure_type)) { + data = ((Scheme_Closure *)cl->array[i])->code; + } else { + data = (Scheme_Closure_Data *)cl->array[i]; + } + + le = unresolve_closure_data_2(data, ui); + if (!le) return_NULL; + + cl2->array[i] = le; + } + + return (Scheme_Object *)cl2; + } + case scheme_let_value_type: + { + Scheme_Let_Value *lv = (Scheme_Let_Value *)e; + Scheme_Object *val, *body; + val = unresolve_expr_2(lv->value, ui, 0); + if (!val) return_NULL; + + body = unresolve_expr_2(lv->body, ui, 0); + if (!body) return_NULL; + + return (Scheme_Object *)unresolve_let_value(lv, ui, val, body); + } + case scheme_quote_syntax_type: + { + Scheme_Quote_Syntax *qs = (Scheme_Quote_Syntax *)e; + Scheme_Local *cqs; + + cqs = (Scheme_Local *)scheme_malloc_atomic_tagged(sizeof(Scheme_Local)); + cqs->iso.so.type = scheme_compiled_quote_syntax_type; + cqs->position = qs->position; + return (Scheme_Object *)cqs; + } + default: + if (SCHEME_TYPE(e) > _scheme_values_types_) { + if (scheme_compiled_duplicate_ok(e, 1) || !(ui->inlining)) + return e; + } + + scheme_signal_error("internal error: no unresolve for: %d", SCHEME_TYPE(e)); + return_NULL; + } +} + +Scheme_Object *scheme_unresolve_top(Scheme_Object* o, Comp_Prefix **cp) { + Scheme_Compilation_Top *top = (Scheme_Compilation_Top *)o; + Scheme_Object *code = top->code; + Resolve_Prefix *rp = top->prefix; + Comp_Prefix *c; + Unresolve_Info *ui; + ui = new_unresolve_info(NULL); + ui->inlining = 0; + code = unresolve_expr_2(code, ui, 0); + if (!code) return_NULL; + c = unresolve_prefix(rp, ui); + *cp = c; + return code; +} + +Scheme_Object *unresolve_closure_data(Scheme_Closure_Data *rdata, Unresolve_Info *ui) { Scheme_Closure_Data *data; Scheme_Object *body; @@ -3352,7 +4623,6 @@ Scheme_Object *unresolve_closure(Scheme_Closure_Data *rdata, Unresolve_Info *ui) } data = MALLOC_ONE_TAGGED(Scheme_Closure_Data); - data->iso.so.type = scheme_compiled_unclosed_procedure_type; SCHEME_CLOSURE_DATA_FLAGS(data) = (SCHEME_CLOSURE_DATA_FLAGS(rdata) @@ -3361,10 +4631,10 @@ Scheme_Object *unresolve_closure(Scheme_Closure_Data *rdata, Unresolve_Info *ui) data->num_params = rdata->num_params; data->name = rdata->name; - pos = unresolve_stack_push(ui, data->num_params, 0); + pos = unresolve_stack_push(ui, data->num_params, 0, 0); if (rdata->closure_size) { - data_pos = unresolve_stack_push(ui, rdata->closure_size, 1); + data_pos = unresolve_stack_push(ui, rdata->closure_size, 1, 0); /* remap closure slots: */ for (i = rdata->closure_size; i--; ) { int mp; @@ -3422,10 +4692,50 @@ static Scheme_Object *unresolve_expr_k(void) return unresolve_expr(e, ui, p->ku.k.i1); } -static void check_nonleaf_rator(Scheme_Object *rator, Unresolve_Info *ui) +Scheme_Object *scheme_unresolve(Scheme_Object *iv, int argc, int *_has_cases) { - if (!scheme_check_leaf_rator(rator, NULL)) - ui->has_non_leaf = 1; + Scheme_Object *o; + Scheme_Closure_Data *data = NULL; + + o = SCHEME_VEC_ELS(iv)[1]; + + if (SAME_TYPE(SCHEME_TYPE(o), scheme_closure_type)) + data = ((Scheme_Closure *)o)->code; + else if (SAME_TYPE(SCHEME_TYPE(o), scheme_unclosed_procedure_type)) + data = (Scheme_Closure_Data *)o; + else if (SAME_TYPE(SCHEME_TYPE(o), scheme_case_lambda_sequence_type) + || SAME_TYPE(SCHEME_TYPE(o), scheme_case_closure_type)) { + Scheme_Case_Lambda *seqin = (Scheme_Case_Lambda *)o; + int i, cnt; + cnt = seqin->count; + if (cnt > 1) *_has_cases = 1; + for (i = 0; i < cnt; i++) { + if (SAME_TYPE(SCHEME_TYPE(seqin->array[i]), scheme_closure_type)) { + /* An empty closure, created at compile time */ + data = ((Scheme_Closure *)seqin->array[i])->code; + } else { + data = (Scheme_Closure_Data *)seqin->array[i]; + } + if ((!(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST) + && (data->num_params == argc)) + || ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST) + && (data->num_params - 1 <= argc))) + break; + else + data = NULL; + } + } else + data = NULL; + + if (!data) + return_NULL; + + if (data->closure_size) + return_NULL; + + /* convert an optimized & resolved closure back to compiled form: */ + return unresolve_closure_data(data, + new_unresolve_info((Scheme_Prefix *)SCHEME_VEC_ELS(iv)[2])); } @@ -3489,7 +4799,7 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a ui->body_size += app->num_args; check_nonleaf_rator(app->args[0], ui); - pos = unresolve_stack_push(ui, app->num_args, 1); + pos = unresolve_stack_push(ui, app->num_args, 1, 0); app2 = scheme_malloc_application(app->num_args+1); @@ -3512,7 +4822,7 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a ui->body_size += 1; check_nonleaf_rator(app->rator, ui); - pos = unresolve_stack_push(ui, 1, 1); + pos = unresolve_stack_push(ui, 1, 1, 0); rator = unresolve_expr(app->rator, ui, 1); if (!rator) return_NULL; @@ -3537,7 +4847,7 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a ui->body_size += 2; check_nonleaf_rator(app->rator, ui); - pos = unresolve_stack_push(ui, 2, 1); + pos = unresolve_stack_push(ui, 2, 1, 0); rator = unresolve_expr(app->rator, ui, 1); if (!rator) return_NULL; @@ -3595,7 +4905,7 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a lh->num_clauses = lv->count; SCHEME_LET_FLAGS(lh) += SCHEME_LET_RECURSIVE; - pos = unresolve_stack_push(ui, lv->count, 0); + pos = unresolve_stack_push(ui, lv->count, 0, 0); for (i = lv->count; i--; ) { rhs = unresolve_expr(lr->procs[i], ui, 0); @@ -3645,12 +4955,12 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a Scheme_Compiled_Let_Value *clv; int *flags, pos; - pos = unresolve_stack_push(ui, 1, 1 /* => post-bind RHS */); + pos = unresolve_stack_push(ui, 1, 1 /* => post-bind RHS */, 0); rhs = unresolve_expr(lo->value, ui, 0); if (!rhs) return_NULL; (void)unresolve_stack_pop(ui, pos, 0); - pos = unresolve_stack_push(ui, 1, 0); + pos = unresolve_stack_push(ui, 1, 0, 0); body = unresolve_expr(lo->body, ui, 0); if (!body) return_NULL; flags = unresolve_stack_pop(ui, pos, 1); @@ -3686,7 +4996,7 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a scheme_hash_set(ui->closures, e, scheme_true); - r = unresolve_closure(SCHEME_COMPILED_CLOS_CODE(e), ui); + r = unresolve_closure_data(SCHEME_COMPILED_CLOS_CODE(e), ui); scheme_hash_set(ui->closures, e, NULL); @@ -3694,7 +5004,7 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a } case scheme_unclosed_procedure_type: { - return unresolve_closure((Scheme_Closure_Data *)e, ui); + return unresolve_closure_data((Scheme_Closure_Data *)e, ui); } default: if (SCHEME_TYPE(e) > _scheme_values_types_) { @@ -3705,52 +5015,6 @@ static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int a } } -Scheme_Object *scheme_unresolve(Scheme_Object *iv, int argc, int *_has_cases) -{ - Scheme_Object *o; - Scheme_Closure_Data *data = NULL; - - o = SCHEME_VEC_ELS(iv)[1]; - - if (SAME_TYPE(SCHEME_TYPE(o), scheme_closure_type)) - data = ((Scheme_Closure *)o)->code; - else if (SAME_TYPE(SCHEME_TYPE(o), scheme_unclosed_procedure_type)) - data = (Scheme_Closure_Data *)o; - else if (SAME_TYPE(SCHEME_TYPE(o), scheme_case_lambda_sequence_type) - || SAME_TYPE(SCHEME_TYPE(o), scheme_case_closure_type)) { - Scheme_Case_Lambda *seqin = (Scheme_Case_Lambda *)o; - int i, cnt; - cnt = seqin->count; - if (cnt > 1) *_has_cases = 1; - for (i = 0; i < cnt; i++) { - if (SAME_TYPE(SCHEME_TYPE(seqin->array[i]), scheme_closure_type)) { - /* An empty closure, created at compile time */ - data = ((Scheme_Closure *)seqin->array[i])->code; - } else { - data = (Scheme_Closure_Data *)seqin->array[i]; - } - if ((!(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST) - && (data->num_params == argc)) - || ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST) - && (data->num_params - 1 <= argc))) - break; - else - data = NULL; - } - } else - data = NULL; - - if (!data) - return_NULL; - - if (data->closure_size) - return_NULL; - - /* convert an optimized & resolved closure back to compiled form: */ - return unresolve_closure(data, - new_unresolve_info((Scheme_Prefix *)SCHEME_VEC_ELS(iv)[2])); -} - /*========================================================================*/ /* precise GC traversers */ /*========================================================================*/ diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 2ed38ebc30..45e66df415 100644 --- a/racket/src/racket/src/schminc.h +++ b/racket/src/racket/src/schminc.h @@ -14,7 +14,7 @@ #define USE_COMPILED_STARTUP 1 -#define EXPECTED_PRIM_COUNT 1132 +#define EXPECTED_PRIM_COUNT 1133 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 6335f1501c..33846fcf59 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1415,7 +1415,7 @@ typedef struct { with a chain of Scheme_Compiled_Let_Value records as its body, where there's one Scheme_Compiled_Let_Value for each binding clause. A `let*' is normally expanded to nested `let's before - compilation, but the intermediate format also supposrts `let*', + compilation, but the intermediate format also supports `let*', which is useful mostly for converting a simple enough `letrec' form into `let*. @@ -1542,7 +1542,7 @@ typedef struct Scheme_Let_Value { Scheme_Object *body; } Scheme_Let_Value; -#define SCHEME_LET_AUTOBOX(lh) MZ_OPT_HASH_KEY(&lh->iso) +#define SCHEME_LET_VALUE_AUTOBOX(lv) MZ_OPT_HASH_KEY(&lv->iso) typedef struct Scheme_Let_One { Scheme_Inclhash_Object iso; /* keyex used for eval_type + flonum/unused (and can't be hashed) */ @@ -1563,6 +1563,8 @@ typedef struct Scheme_Let_Void { Scheme_Object *body; } Scheme_Let_Void; +#define SCHEME_LET_VOID_AUTOBOX(lv) MZ_OPT_HASH_KEY(&lv->iso) + typedef struct Scheme_Letrec { Scheme_Object so; mzshort count; @@ -2949,6 +2951,10 @@ Scheme_Object *scheme_register_toplevel_in_comp_prefix(Scheme_Object *var, Comp_ void scheme_register_unbound_toplevel(Scheme_Comp_Env *env, Scheme_Object *id); Scheme_Object *scheme_register_stx_in_prefix(Scheme_Object *var, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec); +Scheme_Object *scheme_register_stx_in_comp_prefix(Scheme_Object *var, Comp_Prefix *cp); +void scheme_register_unsafe_in_prefix(Scheme_Comp_Env *env, + Scheme_Compile_Info *rec, int drec, + Scheme_Env *menv); void scheme_merge_undefineds(Scheme_Comp_Env *exp_env, Scheme_Comp_Env *env); void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object *a, @@ -3024,6 +3030,7 @@ Scheme_Object *scheme_make_noninline_proc(Scheme_Object *e); Scheme_Object *scheme_resolve_expr(Scheme_Object *, Resolve_Info *); Scheme_Object *scheme_resolve_list(Scheme_Object *, Resolve_Info *); Scheme_Object *scheme_unresolve(Scheme_Object *, int argv, int *_has_cases); +Scheme_Object *scheme_unresolve_top(Scheme_Object *, Comp_Prefix **); int scheme_check_leaf_rator(Scheme_Object *le, int *_flags); diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 391dba2975..2dd3e70717 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.8" +#define MZSCHEME_VERSION "6.2.900.9" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 8 +#define MZSCHEME_VERSION_W 9 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/validate.c b/racket/src/racket/src/validate.c index d9c9ec7211..c73b0faea4 100644 --- a/racket/src/racket/src/validate.c +++ b/racket/src/racket/src/validate.c @@ -1798,16 +1798,16 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr, for (i = 0; i < c; i++, p++) { if ((q < 0) || (p < 0) - || (SCHEME_LET_AUTOBOX(lv) && ((p >= depth) + || (SCHEME_LET_VALUE_AUTOBOX(lv) && ((p >= depth) || ((stack[p] != VALID_BOX) && (stack[p] != VALID_BOX_NOCLEAR)))) - || (!SCHEME_LET_AUTOBOX(lv) && ((p >= letlimit) + || (!SCHEME_LET_VALUE_AUTOBOX(lv) && ((p >= letlimit) || !(WHEN_CAN_RESET_STACK_SLOT(stack[p] == VALID_VAL) || WHEN_CAN_RESET_STACK_SLOT(stack[p] == VALID_VAL_NOCLEAR) || (stack[p] == VALID_UNINIT))))) scheme_ill_formed_code(port); - if (!SCHEME_LET_AUTOBOX(lv)) { + if (!SCHEME_LET_VALUE_AUTOBOX(lv)) { if (stack[p] != VALID_VAL_NOCLEAR) stack[p] = VALID_VAL; } @@ -1827,7 +1827,7 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr, if ((c < 0) || (c > delta)) scheme_ill_formed_code(port); - if (SCHEME_LET_AUTOBOX(lv)) { + if (SCHEME_LET_VOID_AUTOBOX(lv)) { for (i = 0; i < c; i++) { stack[--delta] = VALID_BOX; } From 335db1d1fbf5fa1b15f6b3a9abfb2a088627e446 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 10 Aug 2015 17:10:11 -0600 Subject: [PATCH 014/381] update "base" version --- pkgs/base/info.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 925cde7806..8590b2af27 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.8") +(define version "6.2.900.9") (define deps `("racket-lib" ["racket" #:version ,version])) From 1757348b23951fb0a6729db281b76c358dda3f7c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 10 Aug 2015 17:14:09 -0600 Subject: [PATCH 015/381] repairs for MSVC Don't use `for (int i ....`, which is too modern. --- racket/src/racket/src/resolve.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 5f8800a6ca..b3c3ec8b74 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -3670,7 +3670,8 @@ static Scheme_Object *unresolve_let_void(Scheme_Object *e, Unresolve_Info *ui) { } case scheme_sequence_type: { Scheme_Sequence *seq = (Scheme_Sequence *)o; - for (int i = 0; i < seq->count - 1; i++) { + int i; + for (i = 0; i < seq->count - 1; i++) { if (!SAME_TYPE(SCHEME_TYPE(seq->array[i]), scheme_local_type)) { scheme_signal_error("internal error: unexpected form in sequence: %d", SCHEME_TYPE(o)); } @@ -3795,7 +3796,8 @@ void locate_cyclic_closures(Scheme_Object *e, Unresolve_Info *ui) { case scheme_splice_sequence_type: { Scheme_Sequence *seq = (Scheme_Sequence *)e; - for (int i = 0; i < seq->count; i++) { + int i; + for (i = 0; i < seq->count; i++) { locate_cyclic_closures(seq->array[i], ui); } } @@ -3803,7 +3805,8 @@ void locate_cyclic_closures(Scheme_Object *e, Unresolve_Info *ui) { case scheme_application_type: { Scheme_App_Rec *app = (Scheme_App_Rec *)e; - for (int i = 0; i < app->num_args + 1; i++) { + int i; + for (i = 0; i < app->num_args + 1; i++) { locate_cyclic_closures(app->args[i], ui); } } @@ -3849,7 +3852,8 @@ void locate_cyclic_closures(Scheme_Object *e, Unresolve_Info *ui) { case scheme_letrec_type: { Scheme_Letrec *lr = (Scheme_Letrec *)e; - for (int i = 0; i < lr->count; i++) { + int i; + for (i = 0; i < lr->count; i++) { locate_cyclic_closures(lr->procs[i], ui); } locate_cyclic_closures(lr->body, ui); @@ -3927,7 +3931,8 @@ void locate_cyclic_closures(Scheme_Object *e, Unresolve_Info *ui) { case scheme_case_lambda_sequence_type: { Scheme_Case_Lambda *cl = (Scheme_Case_Lambda *)e; - for (int i = 0; i < cl->count; i++) { + int i; + for (i = 0; i < cl->count; i++) { locate_cyclic_closures(cl->array[i], ui); } } From 22bf10e5649b07a0ffe37aa7f384ce0992491068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Fri, 7 Aug 2015 13:41:46 +0200 Subject: [PATCH 016/381] Fixed typo in the docs for normal-case-path. --- pkgs/racket-doc/scribblings/reference/paths.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/paths.scrbl b/pkgs/racket-doc/scribblings/reference/paths.scrbl index 0a3d383e59..6b127c9b60 100644 --- a/pkgs/racket-doc/scribblings/reference/paths.scrbl +++ b/pkgs/racket-doc/scribblings/reference/paths.scrbl @@ -452,10 +452,10 @@ information on simplifying paths.} Returns @racket[path] with ``normalized'' case letters. For @|AllUnix| paths, this procedure always returns the input path, because filesystems for these platforms can be case-sensitive. For Windows -paths, if @racket[path] does not start @litchar{\\?\}, the +paths, if @racket[path] does not start with @litchar{\\?\}, the resulting string uses only lowercase letters, based on the current locale. In addition, for Windows paths when the path does not start -@litchar{\\?\}, all @litchar{/}s are converted to +with @litchar{\\?\}, all @litchar{/}s are converted to @litchar{\}s, and trailing spaces and @litchar{.}s are removed. The @racket[path] argument can be a path for any platform, but beware From 666da0b2155a006025b85ae1b9c1b33dd5b8ca65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Fri, 7 Aug 2015 13:46:54 +0200 Subject: [PATCH 017/381] =?UTF-8?q?In=20the=20docs=20for=20normal-case-pat?= =?UTF-8?q?h,=20replaced=20=E2=80=9Cletter=E2=80=9D=20with=20=E2=80=9Cchar?= =?UTF-8?q?acter=E2=80=9D,=20to=20avoid=20possible=20confusion=20with=20dr?= =?UTF-8?q?ive=20letters.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkgs/racket-doc/scribblings/reference/paths.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/paths.scrbl b/pkgs/racket-doc/scribblings/reference/paths.scrbl index 6b127c9b60..e28a831fab 100644 --- a/pkgs/racket-doc/scribblings/reference/paths.scrbl +++ b/pkgs/racket-doc/scribblings/reference/paths.scrbl @@ -449,7 +449,7 @@ information on simplifying paths.} @defproc[(normal-case-path [path (or/c path-string? path-for-some-system?)]) path-for-some-system?]{ -Returns @racket[path] with ``normalized'' case letters. For @|AllUnix| +Returns @racket[path] with ``normalized'' case characters. For @|AllUnix| paths, this procedure always returns the input path, because filesystems for these platforms can be case-sensitive. For Windows paths, if @racket[path] does not start with @litchar{\\?\}, the From 6fe8f635e42d7531a3f2675e5d34a622aceb2032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=B9=E5=9F=8E?= Date: Sat, 1 Aug 2015 22:12:02 +0800 Subject: [PATCH 018/381] update packges sources Add Racket package manager to package sources --- pkgs/racket-doc/scribblings/guide/other.scrbl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/other.scrbl b/pkgs/racket-doc/scribblings/guide/other.scrbl index decc903a09..1a9b8ea633 100644 --- a/pkgs/racket-doc/scribblings/guide/other.scrbl +++ b/pkgs/racket-doc/scribblings/guide/other.scrbl @@ -28,5 +28,10 @@ many other installed libraries. Run @exec{raco docs} to find documentation for libraries that are installed on your system and specific to your user account. -@link["http://planet.plt-racket.org/"]{@|PLaneT|} offers even more -downloadable packages contributed by Racketeers. +@link["http://pkgs.racket-lang.org/"]{The Racket package repository} +offer even more downloadable packages that are contributed by +Racketeers. + +The legacy @link["http://planet.racket-lang.org/"]{@|PLaneT|} site +offers additional packages, although maintained packages have +generally migrated to the newer package repository. \ No newline at end of file From 1d99ced2ea3c672757e2e41f157ada79664c96c3 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 10 Aug 2015 18:02:03 -0400 Subject: [PATCH 019/381] Add caveat for free-id-tables & changing bindings --- .../syntax/scribblings/id-table.scrbl | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/syntax/scribblings/id-table.scrbl b/pkgs/racket-doc/syntax/scribblings/id-table.scrbl index 462e838f1a..a1ad334f79 100644 --- a/pkgs/racket-doc/syntax/scribblings/id-table.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/id-table.scrbl @@ -1,5 +1,10 @@ #lang scribble/doc -@(require "common.rkt" (for-label syntax/id-table racket/dict)) +@(require "common.rkt" + scribble/eval + (for-label syntax/id-table racket/dict)) + +@(define id-table-eval (make-base-eval)) +@(id-table-eval '(require (for-syntax racket/base syntax/id-table))) @title[#:tag "idtable"]{Dictionaries with Identifier Keys} @@ -19,6 +24,41 @@ dictionary interface of @racketmodname[racket/dict], so all of the appropriate generic functions (@racket[dict-ref], @racket[dict-map], etc) can be used on free-identifier tables. +A caveat for using these tables is that a lookup can fail with +unexpected results if the binding of an identifier changes between +key-value insertion and the lookup. + +For example, consider the following use: + +@interaction[#:eval id-table-eval +(define-syntax-rule (m) + (begin + (begin-for-syntax + (define table (make-free-id-table)) + (code:comment "set table entry to #t") + (free-id-table-set! table #'x #t) + (code:comment "sanity check, it's set to #t") + (displayln (free-id-table-ref table #'x #f))) + + (define x 'defined-now) + + (begin-for-syntax + (code:comment "might expect to get #t, but prints #f") + (displayln (free-id-table-ref table #'x #f))))) + +(m)] + +The macro @racket[m] expands to code that initializes an identifier table +at compile-time and inserts a key-value pair for @racket[#'x] and +@racket[#t]. The @racket[#'x] identifier has no binding, however, until +the definition @racket[(define x 'defined-now)] is evaluated. + +As a result, the lookup at the end of @racket[m] will return @racket[#f] +instead of @racket[#t] because the binding symbol for @racket[#'x] changes +after the initial key-value pair is put into the table. If the definition +is evaluated @emph{before} the initial insertion, both expressions will +print @racket[#t]. + @deftogether[[ @defproc[(make-free-id-table [init-dict dict? null] @@ -234,3 +274,5 @@ Like the procedures for free-identifier tables for bound-identifier tables, which use @racket[bound-identifier=?] to compare keys. } + +@close-eval[id-table-eval] \ No newline at end of file From b16f0b24b7a6117c1c25c1d37b26b9ddbf27c267 Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Tue, 17 Feb 2015 16:34:20 -0500 Subject: [PATCH 020/381] Improvements to unit/c contracts in preparation for unit support in typed/racket Changes: - Allow unit contracts to import and export the same signature. - Add "invoke" contracts that will wrap the result of invoking a unit contract, no wrapping occurs when a body contract is not specified - Improve error messages - Support for init-depend clauses in unit contracts. - Fix documentation to refelct the above - Overhaul of unit related tests Handling init-depend clauses in unit contracts is a rather large and somewhat non-backwards-compatible change to unit contracts. Unit contracts must now specify at least as many initialization dependencies as the unit value being contracted, but may include more. These new dependencies are now actually specified in the unit wrapper so that they will be checked by compound-unit expressions. This commit also adds more information to the first-order-check error messages. If a unit imports tagged signatures, previously the errror message did not specify which tag was missing from the unit contract. Now the tag is printed along with the signature name. Documentation has been edited to reflect the changes to unit/c contracts made by this commit. Additionally this commit overhauls all tests for units and unit contracts. Test cases now actually check that expected error messages are triggered when checking contract, syntax, and runtime errors. Test forms now expand into uses of rackunit's check-exn form so only test failures are reported and all tests in a file are run on every run of the test file. --- .../scribblings/reference/units.scrbl | 40 +- pkgs/racket-test/tests/units/test-harness.rkt | 30 +- pkgs/racket-test/tests/units/test-runtime.rkt | 11 +- .../tests/units/test-unit-contracts.rkt | 323 ++- pkgs/racket-test/tests/units/test-unit.rkt | 2458 +++++++++-------- .../racket/private/unit-contract-syntax.rkt | 80 +- .../collects/racket/private/unit-contract.rkt | 115 +- racket/collects/racket/unit.rkt | 30 +- 8 files changed, 1834 insertions(+), 1253 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/units.scrbl b/pkgs/racket-doc/scribblings/reference/units.scrbl index 0a244a281a..6f8da3ee96 100644 --- a/pkgs/racket-doc/scribblings/reference/units.scrbl +++ b/pkgs/racket-doc/scribblings/reference/units.scrbl @@ -700,10 +700,21 @@ Expands to a @racket[provide] of all identifiers implied by the @section[#:tag "unitcontracts"]{Unit Contracts} -@defform/subs[#:literals (import export) - (unit/c (import sig-block ...) (export sig-block ...)) +@defform/subs[#:literals (import export values init-depend) + (unit/c + (import sig-block ...) + (export sig-block ...) + init-depends-decl + optional-body-ctc) ([sig-block (tagged-sig-id [id contract] ...) - tagged-sig-id])]{ + tagged-sig-id] + [init-depends-decl + code:blank + (init-depend tagged-sig-id ...)] + [optional-body-ctc + code:blank + contract + (values contract ...)])]{ A @deftech{unit contract} wraps a unit and checks both its imported and exported identifiers to ensure that they match the appropriate contracts. @@ -711,21 +722,30 @@ This allows the programmer to add contract checks to a single unit value without adding contracts to the imported and exported signatures. The unit value must import a subset of the import signatures and export a -superset of the export signatures listed in the unit contract. Any -identifier which is not listed for a given signature is left alone. -Variables used in a given @racket[contract] expression first refer to other -variables in the same signature, and then to the context of the -@racket[unit/c] expression.} +superset of the export signatures listed in the unit contract. Additionally, +the unit value must declare initialization dependencies that are a subset of +those specified in the unit contract. Any identifier which is not listed +for a given signature is left alone. Variables used in a given +@racket[contract] expression first refer to other variables in the same +signature, and then to the context of the @racket[unit/c] expression. +If a body contract is specified then the result of invoking the unit value +is wrapped with the given contract, if no body contract is supplied then +no wrapping occurs when the unit value is invoked.} -@defform/subs[#:literals (import export) +@defform/subs[#:literals (import export values) (define-unit/contract unit-id (import sig-spec-block ...) (export sig-spec-block ...) init-depends-decl + optional-body-ctc unit-body-expr-or-defn ...) ([sig-spec-block (tagged-sig-spec [id contract] ...) - tagged-sig-spec])]{ + tagged-sig-spec] + [optional-body-ctc + code:blank + (code:line #:invoke/contract contract) + (code:line #:invoke/contract (values contract ...))])]{ The @racket[define-unit/contract] form defines a unit compatible with link inference whose imports and exports are contracted with a unit contract. The unit name is used for the positive blame of the contract.} diff --git a/pkgs/racket-test/tests/units/test-harness.rkt b/pkgs/racket-test/tests/units/test-harness.rkt index 42d5f523b9..849161751c 100644 --- a/pkgs/racket-test/tests/units/test-harness.rkt +++ b/pkgs/racket-test/tests/units/test-harness.rkt @@ -1,5 +1,5 @@ (module test-harness racket - (require syntax/stx) + (require syntax/stx rackunit) (provide (all-defined-out)) @@ -35,28 +35,24 @@ (define-syntax test-syntax-error (syntax-rules () ((_ err expr) - (with-handlers ((exn:fail:syntax? (lambda (exn) - (printf "get expected syntax error \"~a\"\n got message \"~a\"\n\n" - err - (exn-message exn))))) - (expand #'expr) - (error 'test-syntax-error "expected syntax error \"~a\" on ~a, got none" err 'expr))))) + (check-exn + (lambda (e) (and (exn:fail:syntax? e) + (regexp-match? (regexp-quote err) + (exn-message e)))) + (lambda () (expand #'expr)))))) (define-syntax test-runtime-error (syntax-rules () ((_ err-pred err expr) - (with-handlers ((err-pred (lambda (exn) - (printf "got expected runtime error \"~a\"\n got message \"~a\"\n\n" - err - (exn-message exn))))) - expr - (error 'test-runtime-error "expected runtime error \"~a\" on ~a, got none" err 'expr))))) + (check-exn + (λ (exn) (and (err-pred exn) + (let ([msg (exn-message exn)]) + (and (regexp-match? (regexp-quote err) msg))))) + (λ () expr (void)))))) (define-syntax test (syntax-rules () ((_ expected-value expr) - (test equal? expected-value expr)) + (check-equal? expected-value expr)) ((_ cmp expected-value expr) - (let ((v expr)) - (unless (cmp expected-value v) - (error 'test "expected ~a to evaluate to ~a, got ~a" 'expr 'expected-value v))))))) + (check cmp expected-value expr))))) diff --git a/pkgs/racket-test/tests/units/test-runtime.rkt b/pkgs/racket-test/tests/units/test-runtime.rkt index 490c4f6c46..ea92546345 100644 --- a/pkgs/racket-test/tests/units/test-runtime.rkt +++ b/pkgs/racket-test/tests/units/test-runtime.rkt @@ -4,7 +4,8 @@ racket/private/unit-runtime) ;; check-unit -(test-runtime-error exn:fail:contract? "check-unit: not a unit" +(test-runtime-error exn:fail:contract? + "result of unit expression was not a unit" (check-unit 1 'check-unit)) (test (void) @@ -27,7 +28,8 @@ 'check-helper #f)) -(test-runtime-error exn:fail:contract? "check-helper: missing signature" +(test-runtime-error exn:fail:contract? + "expects a unit with an export for tag t with signature c, which the given unit does not supply" (check-helper sub-vector #((c . #((t . r4) (t . r1) (t . r2) (t . r3)))) 'check-helper @@ -44,12 +46,11 @@ #((a . #((t . r5) (t . r2) (t . r3)))) 'check-helper #f)) -(test-runtime-error exn:fail:contract? "check-helper: ambiguous signature" +(test-runtime-error exn:fail:contract? + "expects a unit with an export for tag t with signature c, which the given unit supplies multiple times" (check-helper sub-vector2 #((c . #((t . r2) (t . r3)))) 'check-helper #f)) ;; check-deps ;;UNTESTED - -(displayln "tests passed") diff --git a/pkgs/racket-test/tests/units/test-unit-contracts.rkt b/pkgs/racket-test/tests/units/test-unit-contracts.rkt index 904a1175fa..04c6b473f3 100644 --- a/pkgs/racket-test/tests/units/test-unit-contracts.rkt +++ b/pkgs/racket-test/tests/units/test-unit-contracts.rkt @@ -2,7 +2,8 @@ (require "test-harness.rkt" racket/unit - racket/contract) + racket/contract + rackunit) (define temp-unit-blame-re "\\(unit temp[0-9]*\\)") (define top-level "top-level") @@ -34,25 +35,13 @@ (define-syntax test-contract-error/regexp (syntax-rules () ((_ blame obj err expr) - (with-handlers ((exn:fail:contract? - (lambda (exn) - (let ([msg (exn-message exn)]) - (cond - [(not (match-blame blame msg)) - (error 'test-contract-error - "blame \"~a\" not found in:\n\"~a\"" - blame msg)] - [(not (match-obj obj msg)) - (error 'test-contract-error - "object \"~a\" not found in:\n\"~a\"" - obj msg)] - [else - (printf "got expected contract error \"~a\" on ~a blaming ~a: ok\n\t\"~a\"\n\n" - err obj blame (get-ctc-err msg))]))))) - expr - (error 'test-contract-error - "expected contract error \"~a\" on ~a, got none" - err 'expr))))) + (check-exn (λ (exn) + (and (exn:fail:contract? exn) + (let ([msg (exn-message exn)]) + (and (match-blame blame msg) + (match-obj obj msg) + (regexp-match? err msg))))) + (λ () expr))))) (define-signature sig1 ((contracted [x number?]))) @@ -94,34 +83,39 @@ (define-values (c d) (values "foo" 3))) -(test-syntax-error "misuse of contracted" - contracted) -(test-syntax-error "invalid forms after contracted in signature" +(test-syntax-error + "misuse of define-signature keyword" + contracted) +(test-syntax-error + "expected a list of [id contract]" (define-signature x ((contracted x y)))) -(test-syntax-error "identifier not first part of pair after contracted in signature" +(test-syntax-error + "expected a list of [id contract]" (define-signature x ((contracted [(-> number? number?) x])))) -(test-syntax-error "identifier h? not bound anywhere" +(test-syntax-error + "unbound identifier" (module h?-test racket (define-signature s^ ((define-values (f?) (values number?)) (define-syntaxes (g?) (make-rename-transformer #'number?)) (contracted [f (-> f? (and/c g? h?))]))))) -(test-syntax-error "f not defined in unit exporting sig3" +(test-syntax-error + "undefined export" (unit (import) (export sig3 sig4) (define a #t) (define g zero?) (define (b t) (if t 3 0)))) -(test-contract-error "(unit unit1)" "x" "not a number" +(test-contract-error "(unit unit1)" "x" "number?" (invoke-unit unit1)) -(test-contract-error "(unit unit1)" "x" "not a number" +(test-contract-error "(unit unit1)" "x" "number?" (invoke-unit (compound-unit (import) (export) (link (((S1 : sig1)) unit1) (() unit2 S1))))) -(test-contract-error/regexp temp-unit-blame-re "a" "not a number" +(test-contract-error/regexp temp-unit-blame-re "a" "number?" (invoke-unit (compound-unit (import) (export) (link (((S3 : sig3) (S4 : sig4)) (unit (import) (export sig3 sig4) @@ -131,7 +125,7 @@ (define (b t) (if t 3 0)))) (() unit3 S3 S4))))) -(test-contract-error/regexp temp-unit-blame-re "g" "not a boolean" +(test-contract-error/regexp temp-unit-blame-re "g" "boolean?" (invoke-unit (compound-unit (import) (export) (link (((S3 : sig3) (S4 : sig4)) (unit (import) (export sig3 sig4) @@ -141,7 +135,7 @@ (define (b t) (if t 3 0)))) (() unit3 S3 S4))))) -(test-contract-error "(unit unit4)" "b" "not a boolean" +(test-contract-error "(unit unit4)" "b" "boolean?" (invoke-unit (compound-unit (import) (export) (link (((S3 : sig3) (S4 : sig4)) (unit (import) (export sig3 sig4) @@ -151,7 +145,7 @@ (define (b t) (if t 3 0)))) (() unit4 S3 S4))))) -(test-contract-error "(unit unit5)" "d" "not a symbol" +(test-contract-error "(unit unit5)" "d" "symbol?" (invoke-unit unit5)) (define-unit unit6 @@ -181,7 +175,7 @@ (import) (export sig1))) -(test-contract-error "(unit unit7)" "x" "not a boolean" +(test-contract-error "(unit unit7)" "x" "boolean?" (invoke-unit unit7)) (define-unit unit8 @@ -196,7 +190,7 @@ (export sig2)) (f #t)) -(test-contract-error "(unit unit8)" "f" "not a number" +(test-contract-error "(unit unit8)" "f" "number?" (invoke-unit unit8)) (define-unit unit9 @@ -211,7 +205,7 @@ (export sig2)) (f 3)) -(test-contract-error "(unit unit9-1)" "f" "not a number" +(test-contract-error "(unit unit9-1)" "f" "number?" (invoke-unit unit9)) (define-values/invoke-unit @@ -221,7 +215,7 @@ (import) (export sig2)) -(test-contract-error top-level "f" "not a number" +(test-contract-error top-level "f" "number?" (f #t)) (define-unit unit10 @@ -233,13 +227,13 @@ (let () (define x 0) (define f (lambda (x) #t)) - (test-contract-error "(unit u)" "f" "not a number" + (test-contract-error "(unit u)" "f" "number?" (invoke-unit unit10 (import sig1 sig2)))) (let () (define x 1) (define f values) - (test-contract-error "(unit unit10)" "f" "not a number" + (test-contract-error "(unit unit10)" "f" "number?" (invoke-unit unit10 (import sig1 sig2)))) ;; testing that contracts from extended signatures are checked properly @@ -252,9 +246,9 @@ (define-values/invoke-unit unit11 (import) (export sig3)) - (test-contract-error "(unit unit11)" "f" "not a number" + (test-contract-error "(unit unit11)" "f" "number?" (f 3)) - (test-contract-error top-level "f" "not a number" + (test-contract-error top-level "f" "number?" (f #t))) ;; unit/new-import-export tests @@ -319,7 +313,7 @@ (export) (link [((S : sig8)) unit19] [() unit20 S])) - (test-contract-error "(unit unit19)" "f" "not a number" + (test-contract-error "(unit unit19)" "f" "number?" (invoke-unit unit22))) ;; contracted import -> uncontracted import @@ -340,7 +334,7 @@ (export) (link [((S : sig7)) unit18] [() unit23 S])) - (test-contract-error "(unit unit23)" "f" "not a number" + (test-contract-error "(unit unit23)" "f" "number?" (invoke-unit unit25))) ;; contracted import -> contracted import @@ -369,7 +363,7 @@ (export) (link [((S : sig9)) unit28-1] [() unit26 S])) - (test-contract-error "(unit unit28-1)" "f" "not a number" + (test-contract-error "(unit unit28-1)" "f" "number?" (invoke-unit unit28-2))) ;; uncontracted export -> contracted export @@ -390,7 +384,7 @@ (export) (link [((S : sig8)) unit29] [() unit17 S])) - (test-contract-error "(unit unit17)" "f" "not a number" + (test-contract-error "(unit unit17)" "f" "number?" (invoke-unit unit31))) ;; contracted export -> uncontracted export @@ -411,7 +405,7 @@ (export) (link [((S : sig7)) unit32] [() unit16 S])) - (test-contract-error "(unit unit32)" "f" "not a number" + (test-contract-error "(unit unit32)" "f" "number?" (invoke-unit unit34))) ;; contracted export -> contracted export @@ -440,7 +434,7 @@ (export) (link [((S : sig9)) unit35] [() unit37-1 S])) - (test-contract-error "(unit unit37-1)" "f" "not a number" + (test-contract-error "(unit unit37-1)" "f" "number?" (invoke-unit unit37-2))) ;; Converting units with internal contract violations @@ -456,7 +450,7 @@ (export) (link [((S : sig8)) unit15] [() unit38 S])) - (test-contract-error "(unit unit38)" "f" "not a number" + (test-contract-error "(unit unit38)" "f" "number?" (invoke-unit unit39))) (let () (define-compound-unit unit40 @@ -464,7 +458,7 @@ (export) (link [((S : sig8)) unit19] [() unit38 S])) - (test-contract-error "(unit unit38)" "f" "not a number" + (test-contract-error "(unit unit38)" "f" "number?" (invoke-unit unit40))) ;; contracted import -> uncontracted import @@ -478,7 +472,7 @@ (export) (link [((S : sig7)) unit14] [() unit41 S])) - (test-contract-error "(unit unit17)" "f" "not a number" + (test-contract-error "(unit unit17)" "f" "number?" (invoke-unit unit42))) (let () (define-compound-unit unit43 @@ -486,7 +480,7 @@ (export) (link [((S : sig7)) unit18] [() unit41 S])) - (test-contract-error "(unit unit17)" "f" "not a number" + (test-contract-error "(unit unit17)" "f" "number?" (invoke-unit unit43))) ;; contracted import -> contracted import @@ -504,7 +498,7 @@ (export) (link [((S : sig9)) unit45-1] [() unit44 S])) - (test-contract-error "(unit unit17)" "f" "not a number" + (test-contract-error "(unit unit17)" "f" "number?" (invoke-unit unit45-2))) (let () (define-unit unit46-1 @@ -516,7 +510,7 @@ (export) (link [((S : sig9)) unit46-1] [() unit44 S])) - (test-contract-error "(unit unit17)" "f" "not a number" + (test-contract-error "(unit unit17)" "f" "number?" (invoke-unit unit46-2))) ;; uncontracted export -> contracted export @@ -530,7 +524,7 @@ (export) (link [((S : sig8)) unit47] [() unit13 S])) - (test-contract-error "(unit unit47)" "f" "not a number" + (test-contract-error "(unit unit47)" "f" "number?" (invoke-unit unit48))) (let () (define-compound-unit unit49 @@ -538,7 +532,7 @@ (export) (link [((S : sig8)) unit47] [() unit17 S])) - (test-contract-error "(unit unit17)" "f" "not a number" + (test-contract-error "(unit unit17)" "f" "number?" (invoke-unit unit49))) ;; contracted import -> uncontracted import @@ -552,7 +546,7 @@ (export) (link [((S : sig7)) unit50] [() unit12 S])) - (test-contract-error "(unit unit19)" "f" "not a number" + (test-contract-error "(unit unit19)" "f" "number?" (invoke-unit unit51))) (let () (define-compound-unit unit52 @@ -560,7 +554,7 @@ (export) (link [((S : sig7)) unit50] [() unit16 S])) - (test-contract-error "(unit unit50)" "f" "not a number" + (test-contract-error "(unit unit50)" "f" "number?" (invoke-unit unit52))) ;; contracted export -> contracted export @@ -578,7 +572,7 @@ (export) (link [((S : sig9)) unit53] [() unit54-1 S])) - (test-contract-error "(unit unit19)" "f" "not a number" + (test-contract-error "(unit unit19)" "f" "number?" (invoke-unit unit54-2))) (let () (define-unit unit55-1 @@ -590,7 +584,7 @@ (export) (link [((S : sig9)) unit53] [() unit55-1 S])) - (test-contract-error "(unit unit55-1)" "f" "not a number" + (test-contract-error "(unit unit55-1)" "f" "number?" (invoke-unit unit55-2))) (module m1 racket @@ -628,26 +622,29 @@ (require (prefix-in m2: 'm2)) (m2:z) -(test-contract-error "m2" "U@" "not a symbol" (m2:w)) -(test-contract-error "m1" "U@" "not a string" (m2:v)) +(test-contract-error "m2" "U@" "symbol?" (m2:w)) +(test-contract-error "m1" "U@" "string?" (m2:v)) -(test-syntax-error "no y in sig1" +(test-syntax-error + "identifier not member of signature" (unit/c (import (sig1 [y number?])) (export))) -(test-syntax-error "two xs for sig1" +(test-syntax-error + "duplicate identifier found" (unit/c (import) (export (sig1 [x string?] [x number?])))) -(test-syntax-error "no sig called faux^, so import description matching fails" +(test-syntax-error + "unit/c: unknown signature" (unit/c (import faux^) (export))) -(test-contract-error "(definition bad-export@)" "bad-export@" "unit must export sig1" +(test-contract-error "(definition bad-export@)" "bad-export@" "unit must export signature sig1" (let () (define/contract bad-export@ (unit/c (import) (export sig1)) (unit (import) (export))) bad-export@)) -(test-contract-error "(definition bad-import@)" "bad-import@" "contract must import sig1" +(test-contract-error "(definition bad-import@)" "bad-import@" "contract does not list import sig1" (let () (define/contract bad-import@ (unit/c (import) (export)) @@ -702,7 +699,7 @@ (require (prefix-in m4: 'm4)) -(test-contract-error "m4" "f" "not an x" +(test-contract-error "m4" "f" " x?" (m4:f 3)) (module m4:f racket @@ -720,12 +717,12 @@ (require (prefix-in m4: 'm4:f)) -(test-contract-error "m4:f" "f:f" "not an f:x" +(test-contract-error "m4:f" "f:f" "x?" (m4:f:f 3)) (require (prefix-in m3: 'm3)) -(test-contract-error top-level "build-toys" "not a integer" +(test-contract-error top-level "build-toys" "integer?" (let () (define-values/invoke-unit/infer m3:simple-factory@) (build-toys #f))) @@ -753,7 +750,7 @@ (m5:f 0) -(test-contract-error top-level "U@" "not an x" +(test-contract-error top-level "U@" " x?" (m5:f 3)) (let () @@ -774,7 +771,7 @@ (define-values/invoke-unit/infer V@) (f 0) - (test-contract-error top-level "f" "not an x" + (test-contract-error top-level "f" "zero?" (f 3))) (let () @@ -795,7 +792,7 @@ (define-values/invoke-unit/infer V@) (f 0) - (test-contract-error "(unit V@)" "f" "not an x" + (test-contract-error "(unit V@)" "f" "zero?" (f 3))) (let () @@ -813,11 +810,11 @@ (import) (export) (link U@ V@)) (define-values/invoke-unit/infer U@) y - (test-contract-error top-level "U@" "not a number" + (test-contract-error top-level "U@" "number?" (x #t)) - (test-contract-error "(unit U@)" "U@" "not a number" + (test-contract-error "(unit U@)" "U@" "number?" (x 3)) - (test-contract-error "(unit U@)" "U@" "not a number" + (test-contract-error "(unit U@)" "U@" "number?" (invoke-unit W@))) (let () @@ -831,16 +828,16 @@ (define-unit V@ (import foo^) (export) - (test-contract-error top-level "U@" "not an x" + (test-contract-error top-level "U@" " x?" (f 2)) - (test-contract-error "(unit U@)" "U@" "not an number" + (test-contract-error "(unit U@)" "U@" " number?" (f 3))) (define-compound-unit/infer W@ (import) (export) (link U@ V@)) (define-values/invoke-unit/infer U@) - (test-contract-error top-level "U@" "not an x" + (test-contract-error top-level "U@" " x?" (f 4)) - (test-contract-error "(unit U@)" "U@" "not a number" + (test-contract-error "(unit U@)" "U@" "number?" (f 3)) (invoke-unit W@)) @@ -860,7 +857,7 @@ (define-values/invoke-unit/infer foo@) (f 0) - (test-contract-error top-level "f" "not an x" + (test-contract-error top-level "f" " x?" (f 4)) ;; This is a weird one. The definition for foo@ has two conflicting ;; contracts. Who gets blamed? Still the top-level, since foo@ can't @@ -869,7 +866,7 @@ ;; just be an "overriding" contract, but a) that won't really work and ;; b) what about other units that might link with foo@, that expect ;; the stronger contract? - (test-contract-error top-level "x?" "not a number" + (test-contract-error top-level "x?" "number?" (f #t))) (let () @@ -881,9 +878,9 @@ (struct student (name id))) (define-values/invoke-unit/infer student@) (student "foo" 3) - (test-contract-error top-level "student" "not a string" + (test-contract-error top-level "student" "string?" (student 4 3)) - (test-contract-error top-level "student-id" "not a student" + (test-contract-error top-level "student-id" "student?" (student-id 'a))) ;; Test that prefixing doesn't cause issues. @@ -911,4 +908,164 @@ (define-values/invoke-unit c@ (import) (export s^)) (new-make-t)) -(displayln "tests passed") + +(let () + (define-signature s^ ((contracted [n number?]))) + (define-unit s0@ + (import) + (export s^) + (define n 0)) + + (define-unit s1@ + (import) + (export s^) + (define n 1)) + + (define-unit/contract a0@ + (import) + (export) + #:invoke/contract (-> integer? integer?) + (lambda (n) (add1 n))) + + (define-unit/contract a1@ + (import) + (export) + (init-depend) + #:invoke/contract (-> integer? integer?) + (lambda (n) "bad")) + + ((invoke-unit a0@) 1) + (test-contract-error "(unit a1@)" "a1@" " integer?" ((invoke-unit a1@) 1)) + + (define-unit t@ + (import s^) + (export) + (if (zero? n) "zero" n)) + + (define c@/c (unit/c (import) (export) number?)) + (define/contract c0@ c@/c + (compound-unit (import) (export) (link [((S : s^)) s0@] [() t@ S]))) + (define/contract c1@ c@/c + (compound-unit (import) (export) (link [((S : s^)) s1@] [() t@ S]))) + (test-contract-error "(definition c0@)" "c0@" "number?" (invoke-unit c0@)) + (invoke-unit c1@)) + +;; tests for values case of unit/c contracts + + +(let () + ;; first order + (define c1 (unit/c (import) (export) (values integer?))) + (define c2 (unit/c (import) (export) (values integer? string?))) + + (define/contract u1 c1 (unit (import) (export) 5)) + (define/contract u2 c1 (unit (import) (export) "bad")) + (define/contract u3 c1 (unit (import) (export) (values 1 2))) + (define/contract u4 c2 (unit (import) (export) (values 1 "two"))) + (define/contract u5 c2 (unit (import) (export) (values 1 2))) + (define/contract u6 c2 (unit (import) (export) "bad")) + + ;; passing + (invoke-unit u1) + (invoke-unit u4) + + ;; failing + (test-contract-error "(definition u2)" "u2" "promised: integer?" (invoke-unit u2)) + (test-contract-error "(definition u5)" "u5" "promised: string?" (invoke-unit u5)) + ;; wrong number of values + (test-contract-error "(definition u3)" "u3" "expected 1 values" (invoke-unit u3)) + (test-contract-error "(definition u6)" "u6" "expected 2 values" (invoke-unit u6)) + + ;; higher order + (define c3 (unit/c (import) (export) (values (-> integer? string?)))) + (define c4 (unit/c (import) (export) (values (-> integer? integer?) (-> string? string?)))) + + (define/contract u7 c3 (unit (import) (export) (λ (n) "ok"))) + (define/contract u8 c3 (unit (import) (export) (λ (n) 'bad))) + (define/contract u9 c4 (unit (import) (export) (values (λ (n) n) (λ (s) s)))) + (define/contract u10 c4 (unit (import) (export) (values (λ (n) "bad") (λ (s) 'bad)))) + + (define-values (f1) (invoke-unit u7)) + (define-values (f2) (invoke-unit u8)) + (define-values (f3 f4) (invoke-unit u9)) + (define-values (f5 f6) (invoke-unit u10)) + + ;; ok + (f1 1) + (f3 3) + (f4 "ok") + ;; errors + (test-contract-error "top-level" "u7" "expected: integer?" (f1 "bad")) + (test-contract-error "top-level" "u8" "expected: integer?" (f2 "bad")) + (test-contract-error "(definition u8)" "u8" "promised: string?" (f2 5)) + (test-contract-error "top-level" "u9" "expected: integer?" (f3 "bad")) + (test-contract-error "top-level" "u9" "expected: string?" (f4 5)) + (test-contract-error "top-level" "u10" "expected: integer?" (f5 "bad")) + (test-contract-error "(definition u10)" "u10" "promised: integer?" (f5 5)) + (test-contract-error "(definition u10)" "u10" "promised: string?" (f6 "bad")) + (test-contract-error "top-level" "u10" "expected: string?" (f6 6))) + + + +;; tests for init-depends in unit contracts +(let () + (define-signature a^ ()) + (define-signature b^ ()) + (define-signature c^ ()) + + (define/contract u@ + (unit/c (import a^ b^) (export) (init-depend a^ b^)) + (unit (import a^ b^) (export) (init-depend a^ b^))) + + (define/contract v@ + (unit/c (import a^ b^) (export) (init-depend a^ b^)) + (unit (import a^) (export) (init-depend a^))) + + (test-contract-error + "(definition w@)" "w@" "contract does not list initialization dependency a^" + (let () + (define/contract w@ + (unit/c (import a^) (export)) + (unit (import a^) (export) (init-depend a^))) + w@)) + + ;; make sure that extended dependencies are checked correctly + (define-signature a-sub^ extends a^ ()) + (define/contract x@ + (unit/c (import a-sub^) (export) (init-depend a-sub^)) + (unit (import a^) (export) (init-depend a^))) + + ;; make sure tags are checked correctly for init-depends + (test-contract-error + "(definition y@)" "y@" "contract does not list initialization dependency a^ with tag A" + (let () + (define/contract y@ + (unit/c (import (tag A a^) a^) (export) (init-depend a^)) + (unit (import (tag A a^) a^) (export) (init-depend (tag A a^)))) + y@)) + + (test-syntax-error + "unit/c: initialization dependency on unknown import" + (let () + (define-signature a^ ()) + (define-signature a-sub^ extends a^ ()) + (unit/c (import a^) (export) (init-depend a-sub^)))) + (test-syntax-error + "unit/c: initialization dependency on unknown import" + (let () + (define-signature a^ ()) + (unit/c (import) (export) (init-depend a^)))) + + (test-syntax-error + "unit/c: unknown signature" + (unit/c (import x^) (export) (init-depend))) + + (test-syntax-error + "unit/c: unknown signature" + (unit/c (import) (export) (init-depend x^))) + + (test-syntax-error + "unit/c: unknown signature" + (unit/c (import) (export x^) (init-depend))) + + (void)) diff --git a/pkgs/racket-test/tests/units/test-unit.rkt b/pkgs/racket-test/tests/units/test-unit.rkt index 520056b0ce..c460883198 100644 --- a/pkgs/racket-test/tests/units/test-unit.rkt +++ b/pkgs/racket-test/tests/units/test-unit.rkt @@ -3,7 +3,7 @@ (require (for-syntax racket/private/unit-compiletime racket/private/unit-syntax)) (require "test-harness.rkt" - scheme/unit) + racket/unit) (define-syntax (lookup-sig-mac stx) (parameterize ((error-syntax stx)) @@ -14,14 +14,14 @@ ((make-syntax-delta-introducer (car (signature-vars s)) member-id) (datum->syntax #'id (syntax-e member-id)))) (list (map shift-scope (signature-vars s)) - (map (lambda (def) - (cons (map shift-scope (car def)) - (cdr def))) - (signature-val-defs s)) - (map (lambda (def) - (cons (map shift-scope (car def)) - (cdr def))) - (signature-stx-defs s)))))))) + (map (lambda (def) + (cons (map shift-scope (car def)) + (cdr def))) + (signature-val-defs s)) + (map (lambda (def) + (cons (map shift-scope (car def)) + (cdr def))) + (signature-stx-defs s)))))))) (define-signature x-sig (x)) (define-signature x-sig2 (x)) @@ -39,112 +39,155 @@ (define-signature y-sub extends y-sig (yy)) (define-signature x-sub2 extends x-sig (x2)) - + ;; Keyword errors -(test-syntax-error "misuse of import" - import) -(test-syntax-error "misuse of export" - export) -(test-syntax-error "misuse of init-depend" - init-depend) -(test-syntax-error "misuse of link" - link) -(test-syntax-error "misuse of only" - only) -(test-syntax-error "misuse of except" - except) -(test-syntax-error "misuse of prefix" - prefix) -(test-syntax-error "misuse of rename" - rename) -(test-syntax-error "misuse of tag" - tag) +(test-syntax-error + "misuse of unit keyword" + import) +(test-syntax-error + "misuse of unit keyword" + export) +(test-syntax-error + "misuse of unit keyword" + init-depend) +(test-syntax-error + "misuse of compound-unit keyword" + link) +(test-syntax-error + "misuse of unit import keyword" + only) +(test-syntax-error + "misuse of unit import keyword" + except) +(test-syntax-error + "misuse of unit import and export keyword" + prefix) +(test-syntax-error + "misuse of unit import and export keyword" + rename) +(test-syntax-error + "misuse of unit import and export keyword" + tag) ;; define-signature-forms syntax errors -(test-syntax-error "define-signature-form: missing arguments" - (define-signature-form)) -(test-syntax-error "define-signature-form: missing arguments" - (define-signature-form (a b))) -(test-syntax-error "define-signature-form: too many arguments" - (define-signature-form (a b c d) 1 2)) -(test-syntax-error "define-signature-form: dot" - (define-signature-form (a b) . c)) -(test-syntax-error "define-signature-form: set!" - (let () - (define-signature-form (a b) b) - (set! a 1))) +(test-syntax-error + "bad syntax (not a list)" + (define-signature-form)) +(test-syntax-error + "bad syntax" + (define-signature-form (a b))) +(test-syntax-error + "expected syntax matching (define-signature-form (id id) expr ...)" + (define-signature-form (a b c d) 1 2)) +(test-syntax-error + "bad syntax" + (define-signature-form (a b) . c)) +(test-syntax-error + "illegal use of signature form" + (let () + (define-signature-form (a b) b) + (set! a 1))) -(test-syntax-error "define-signature-form: bad params" - (define-signature-form 1 2)) -(test-syntax-error "define-signature-form: bad params" - (define-signature-form a 2)) -(test-syntax-error "define-signature-form: name not id" - (define-signature-form (1 a) 1)) -(test-syntax-error "define-signature-form: param not id" - (define-signature-form (a 1) 1)) -(test-syntax-error "define-signature-form: param dot" - (define-signature-form (a . b) 1)) +(test-syntax-error + "bad syntax (not a list)" + (define-signature-form 1 2)) +(test-syntax-error + "bad syntax (not a list)" + (define-signature-form a 2)) +(test-syntax-error "define-signature-form: not an identifier" + (define-signature-form (1 a) 1)) +(test-syntax-error + "not an identifier" + (define-signature-form (a 1) 1)) +(test-syntax-error + "bad syntax (not a list)" + (define-signature-form (a . b) 1)) ;; define-signature syntax-errors -(test-syntax-error "define-signature: missing name" - (define-signature)) -(test-syntax-error "define-signature: missing sig" - (define-signature x)) -(test-syntax-error "define-signature: too many args" - (define-signature x (a b) 1)) -(test-syntax-error "define-signature: bad name" - (define-signature 1 (a b))) -(test-syntax-error "define-signature: bad name" - (define-signature x extends 1 (a b))) -(test-syntax-error "define-signature: not a signature" - (define-signature x extends y12 (a b))) -(test-syntax-error "define-signature: not a signature" - (let () (define-signature x extends x (a b)))) -(test-syntax-error "define-signature: bad name" - (define-signature (a . b) (a b))) -(test-syntax-error "define-signature: dot" - (define-signature b . (a b))) -(test-syntax-error "define-signature: dot" - (define-signature b (a b) . 2)) -(test-syntax-error "define-signature: set!" - (let () - (define-signature a (a)) - (set! a 1))) -(test-syntax-error "define-signature: bad sig" - (define-signature x y)) -(test-syntax-error "define-signature: bad sig" - (define-signature x (1))) -(test-syntax-error "define-signature: bad sig" - (define-signature x (a . b))) -(test-syntax-error "define-signature: bad signature form" - (define-signature x ((a)))) -(test-syntax-error "define-signature: bad signature form" - (define-signature x ((define-signature)))) -(test-syntax-error "define-values: malformed (in define-signature)" - (define-signature x ((define-values 1 2)))) -(test-syntax-error "define-signature: bad form (does not return list)" - (let () - (define-signature-form (a b) 1) - (define-signature x ((a 1))))) -(test-syntax-error "define-signature: unknown form" - (let () - (define-signature-form (a b) (list #'(c d))) - (define-signature x ((a 1))) - 1)) -(test-syntax-error "define-signature: duplicate name" - (define-signature x (a a))) -(test-syntax-error "define-signature: duplicate values" - (define-signature x (a (define-values (a) 1)))) -(test-syntax-error "define-signature: duplicate values" - (define-signature x (a (define-values (b b) 1)))) -(test-syntax-error "define-signature: duplicate values" - (define-signature x (a (define-values (b) 1) (define-syntaxes (b) 1)))) -(test-syntax-error "define-signature: duplicate values" - (let () - (define-signature test (y)) - (define-signature x extends test ((define-values (y) 1))))) +(test-syntax-error + "expected syntax matching" + (define-signature)) +(test-syntax-error + "expected syntax matching" + (define-signature x)) +(test-syntax-error + "expected syntax matching" + (define-signature x (a b) 1)) +(test-syntax-error + "not an identifier" + (define-signature 1 (a b))) +(test-syntax-error + "not an identifier" + (define-signature x extends 1 (a b))) +(test-syntax-error + "unknown signature" + (define-signature x extends y12 (a b))) +(test-syntax-error + "unknown signature" + (let () (define-signature x extends x (a b)))) +(test-syntax-error + "not an identifier" + (define-signature (a . b) (a b))) +(test-syntax-error + "expected syntax matching" + (define-signature b . (a b))) +(test-syntax-error + "bad syntax (illegal use of `.')" + (define-signature b (a b) . 2)) +(test-syntax-error + "set!: illegal use of signature name" + (let () + (define-signature a (a)) + (set! a 1))) +(test-syntax-error + "expected syntax matching" + (define-signature x y)) +(test-syntax-error + "define-signature: expected either an identifier or signature form" + (define-signature x (1))) + +(test-syntax-error + "define-signature: bad syntax (illegal use of `.')" + (define-signature x (a . b))) +(test-syntax-error + "define-signature: unknown signature form" + (define-signature x ((a)))) +(test-syntax-error + "define-signature: not a signature form" + (define-signature x ((define-signature)))) +(test-syntax-error + "define-values: bad variable list" + (define-signature x ((define-values 1 2)))) +(test-syntax-error + "define-signature: expected list of results from signature form, got 1" + (let () + (define-signature-form (a b) 1) + (define-signature x ((a 1))))) +(test-syntax-error + "define-signature: unknown signature form" + (let () + (define-signature-form (a b) (list #'(c d))) + (define-signature x ((a 1))) + 1)) +(test-syntax-error + "define-signature: duplicate identifier" + (define-signature x (a a))) +(test-syntax-error + "define-signature: duplicate identifier" + (define-signature x (a (define-values (a) 1)))) +(test-syntax-error + "define-signature: duplicate identifier" + (define-signature x (a (define-values (b b) 1)))) +(test-syntax-error + "define-signature: duplicate identifier" + (define-signature x (a (define-values (b) 1) (define-syntaxes (b) 1)))) +(test-syntax-error + "define-signature: duplicate identifier" + (let () + (define-signature test (y)) + (define-signature x extends test ((define-values (y) 1))))) ;; define-signature (test stx-bound-id=? #'((a b) () ()) @@ -197,7 +240,7 @@ (lookup-sig-mac x))) (let () (define-signature-form (x y) - (list (cdr (syntax-e y)))) + (list (cdr (syntax-e y)))) (test stx-bound-id=? #'((a) () ()) @@ -206,160 +249,205 @@ (lookup-sig-mac z)))) ;; unit syntax errors (without sub-signatures) -(test-syntax-error "unit: bad sig import" - (unit (import 1) (export))) -(test-syntax-error "unit: bad sig export" - (unit (import) (export 1))) -(test-syntax-error "unit: unknown sig import" - (unit (import a) (export))) -(test-syntax-error "unit: unknown sig export" - (unit (import) (export a))) -(test-syntax-error "unit: bad tag (not identifier)" - (unit (import (tag 1 empty-sig)) (export))) -(test-syntax-error "unit: bad tag (not identifier)" - (unit (import) (export (tag 'a empty-sig)))) -(test-syntax-error "define-values: bad syntax (in unit)" - (unit (import) (export) (define-values))) -(test-syntax-error "unit: multiple definition" - (unit (import) (export) (define-values (x x) (values 1 2)))) -(test-syntax-error "unit: multiple definition" - (unit (import) (export) (define-syntaxes (x x) (values 1 2)))) -(test-syntax-error "unit: multiple definition" - (unit (import) (export) (define x 1) (define x 2))) -(test-syntax-error "unit: multiple definition" - (unit (import) (export) (define-syntax x 1) (define-syntax x 2))) -(test-syntax-error "unit: multiple definition" - (unit (import) (export) (define x 1) (define-syntax x 2))) -(test-syntax-error "unit: re-export" - (unit (import x-sig) (export x-sig) (define x 1))) -(test-syntax-error "unit: redefine import" - (unit (import x-sig) (export) (define x 1))) -(test-syntax-error "unit: set! import" - (unit (import x-sig) (export) (set! x 1))) -(test-syntax-error "unit: set! export" - (unit (import) (export x-sig) (define x 1) (set! x 1))) +(test-syntax-error + "unit: bad import spec" + (unit (import 1) (export))) +(test-syntax-error + "unit: bad export spec" + (unit (import) (export 1))) +(test-syntax-error + "unit: unknown signature" + (unit (import a) (export))) +(test-syntax-error + "unit: unknown signature" + (unit (import) (export a))) +(test-syntax-error + "unit: tag must be a symbol" + (unit (import (tag 1 empty-sig)) (export))) +(test-syntax-error + "unit: tag must be a symbol" + (unit (import) (export (tag 'a empty-sig)))) +(test-syntax-error + "define-values: bad syntax (has 0 parts after keyword)" + (unit (import) (export) (define-values))) +(test-syntax-error + "unit: variable defined twice" + (unit (import) (export) (define-values (x x) (values 1 2)))) +(test-syntax-error + "unit: variable defined twice" + (unit (import) (export) (define-syntaxes (x x) (values 1 2)))) +(test-syntax-error + "unit: variable defined twice" + (unit (import) (export) (define x 1) (define x 2))) +(test-syntax-error + "unit: variable defined twice" + (unit (import) (export) (define-syntax x 1) (define-syntax x 2))) +(test-syntax-error + "unit: variable defined twice" + (unit (import) (export) (define x 1) (define-syntax x 2))) +(test-syntax-error + "unit: import x is exported" + (unit (import x-sig) (export x-sig) (define x 1))) +(test-syntax-error + "unit: definition for imported identifier" + (unit (import x-sig) (export) (define x 1))) +(test-syntax-error + "unit: cannot set! imported or exported variables" + (unit (import x-sig) (export) (set! x 1))) +(test-syntax-error + "unit: cannot set! imported or exported variables" + (unit (import) (export x-sig) (define x 1) (set! x 1))) (test-syntax-error "unit: undefined export" - (unit (import) (export x-sig))) + (unit (import) (export x-sig))) (test-syntax-error "unit: undefined export" - (unit (import) (export (prefix x: x-sig)) (define x 1))) -(test-syntax-error "unit: syntax export" - (unit (import) (export x-sig) (define-syntax x 1))) -(test-syntax-error "unit: duplicate import" - (unit (import x-sig x-sig2) (export))) -(test-syntax-error "unit: duplicate export" - (unit (import) (export x-sig x-sig2) (define x 12))) + (unit (import) (export (prefix x: x-sig)) (define x 1))) +(test-syntax-error + "unit: cannot export syntax from a unit" + (unit (import) (export x-sig) (define-syntax x 1))) +(test-syntax-error + "unit: x is imported by multiple signatures" + (unit (import x-sig x-sig2) (export))) +(test-syntax-error + "unit: x is exported by multiple signatures" + (unit (import) (export x-sig x-sig2) (define x 12))) +(test-syntax-error + "unit: duplicate import signature" + (unit (import x-sig (prefix a x-sig)) (export))) +(test-syntax-error + "unit: the signature of x-sig extends this signature" + (unit (import) (export x-sig (prefix a x-sig)) + (define x 1) (define ax 2))) (test-syntax-error "unit: duplicate import signature" - (unit (import x-sig (prefix a x-sig)) (export))) -(test-syntax-error "unit: duplicate export signature" - (unit (import) (export x-sig (prefix a x-sig)) - (define x 1) (define ax 2))) -(test-syntax-error "unit: duplicate import signature" - (unit (import (tag t x-sig) (tag t (prefix a x-sig))) (export))) -(test-syntax-error "unit: duplicate export signature" - (unit (import) (export (tag t x-sig) (tag t (prefix a x-sig))) - (define x 1) (define ax 2))) -(test-syntax-error "unit: duplicate export signature" - (unit (import) (export x-sig x-sig) - (define x 1))) + (unit (import (tag t x-sig) (tag t (prefix a x-sig))) (export))) +(test-syntax-error + "unit: the signature of (tag t x-sig) extends this signature" + (unit (import) (export (tag t x-sig) (tag t (prefix a x-sig))) + (define x 1) (define ax 2))) +(test-syntax-error + "unit: the signature of x-sig extends this signature" + (unit (import) (export x-sig x-sig) + (define x 1))) ;; compound-unit syntax errors (without sub-signatures) -(test-syntax-error "compound-unit: bad import clause" - (compound-unit (import (a empty-sig)) (export) (link))) -(test-syntax-error "compound-unit: import clause bad link id" - (compound-unit (import (1 : empty-sig)) (export) (link))) -(test-syntax-error "compound-unit: import clause unknown sig" - (compound-unit (import (a : empty-si)) (export) (link))) -(test-syntax-error "compound-unit: export bad link id" - (compound-unit (import) (export a 1 b) (link))) -(test-syntax-error "compound-unit: link line bad link id" - (compound-unit (import) (export) (link (((a : empty-sig)) b 1)))) -(test-syntax-error "compound-unit: import clause bad sig id" - (compound-unit (import (a : ())) (export) (link))) -(test-syntax-error "compound-unit: link line clause bad sig id" - (compound-unit (import) (export) (link (((a : "")) b)))) -(test-syntax-error "compound-unit: link line clause bad" - (compound-unit (import) (export) (link (((a empty-sig)) b)))) -(test-syntax-error "compound-unit: link line clause unknown" - (compound-unit (import) (export) (link (((a : b)) b)))) -(test-syntax-error "compound-unit: duplicate link ids" - (compound-unit (import (x : x-sig) (x : y-sig)) (export) (link))) -(test-syntax-error "compound-unit: duplicate link ids" - (compound-unit (import) (export) (link (((x : x-sig) (x : y-sig)) u)))) -(test-syntax-error "compound-unit: duplicate link ids" - (compound-unit (import (x : x-sig)) (export) (link (((x : x-sig)) u)))) -(test-syntax-error "export: unbound link id" - (compound-unit (import) (export a) (link))) -(test-syntax-error "link link: unbound link id" - (compound-unit (import) (export) (link (() u a)))) -(test-syntax-error "compound-unit: re-export" - (compound-unit (import (S : x-sig)) (export S) (link))) -(test-syntax-error "compound-unit: re-export" - (compound-unit (import (tag s (S : x-sig))) (export (tag t S)) (link))) -(test-syntax-error "compound-unit: duplicate export signature" - (compound-unit (import) (export X1 X2) - (link (((X1 : x-sig)) (unit (import) (export x-sig) (define x 1))) - (((X2 : x-sig)) (unit (import) (export x-sig) (define x 1)))))) -(test-syntax-error "compound-unit: duplicate export signature" - (compound-unit (import) (export (tag t X1) (tag t X2)) - (link (((X1 : x-sig)) (unit (import) (export x-sig) (define x 1))) - (((X2 : x-sig)) (unit (import) (export x-sig) (define x 1)))))) +(test-syntax-error + "compound-unit: expected syntax matching ( : ) or ( : (tag ))" + (compound-unit (import (a empty-sig)) (export) (link))) +(test-syntax-error + "compound-unit: expected syntax matching ( : ) or ( : (tag ))" + (compound-unit (import (1 : empty-sig)) (export) (link))) +(test-syntax-error + "compound-unit: unknown signature" + (compound-unit (import (a : empty-si)) (export) (link))) +(test-syntax-error + "compound-unit: not an identifier" + (compound-unit (import) (export a 1 b) (link))) +(test-syntax-error + "compound-unit: not an identifier" + (compound-unit (import) (export) (link (((a : empty-sig)) b 1)))) +(test-syntax-error + "compound-unit: not an identifier" + (compound-unit (import (a : ())) (export) (link))) +(test-syntax-error + "compound-unit: not an identifier" + (compound-unit (import) (export) (link (((a : "")) b)))) +(test-syntax-error + "compound-unit: expected syntax matching ( : ) or ( : (tag ))" + (compound-unit (import) (export) (link (((a empty-sig)) b)))) +(test-syntax-error + "compound-unit: unknown signature" + (compound-unit (import) (export) (link (((a : b)) b)))) +(test-syntax-error + "compound-unit: duplicate linking identifier definition" + (compound-unit (import (x : x-sig) (x : y-sig)) (export) (link))) +(test-syntax-error + "compound-unit: duplicate linking identifier definition" + (compound-unit (import) (export) (link (((x : x-sig) (x : y-sig)) u)))) +(test-syntax-error + "compound-unit: duplicate linking identifier definition" + (compound-unit (import (x : x-sig)) (export) (link (((x : x-sig)) u)))) +(test-syntax-error + "compound-unit: unknown linking identifier" + (compound-unit (import) (export a) (link))) +(test-syntax-error + "compound-unit: unknown linking identifier" + (compound-unit (import) (export) (link (() u a)))) +(test-syntax-error + "compound-unit: cannot directly export an import" + (compound-unit (import (S : x-sig)) (export S) (link))) +(test-syntax-error + "compound-unit: expected syntax matching ( : ) or ( : (tag ))" + (compound-unit (import (tag s (S : x-sig))) (export (tag t S)) (link))) +(test-syntax-error + "compound-unit: the signature of X1 extends this signature" + (compound-unit (import) (export X1 X2) + (link (((X1 : x-sig)) (unit (import) (export x-sig) (define x 1))) + (((X2 : x-sig)) (unit (import) (export x-sig) (define x 1)))))) +(test-syntax-error + "compound-unit: the signature of (tag t X1) extends this signature" + (compound-unit (import) (export (tag t X1) (tag t X2)) + (link (((X1 : x-sig)) (unit (import) (export x-sig) (define x 1))) + (((X2 : x-sig)) (unit (import) (export x-sig) (define x 1)))))) ;; define-values/invoke-unit syntax errors -(test-syntax-error "define-values/invoke-unit: no unit" - (define-values/invoke-unit)) -(test-syntax-error "define-values/invoke-unit: dot" - (define-values/invoke-unit x y . x)) -(test-syntax-error "define-values/invoke-unit: bad sig" - (define-values/invoke-unit 1 1)) -(test-syntax-error "define-values/invoke-unit: duplicate exports" - (define-values/invoke-unit (unit (import) (export (prefix x: x-sig) x-sig2) - (define x 1) - (define x:x 2)) - x-sig x-sig2)) +(test-syntax-error + "define-values/invoke-unit: missing unit" + (define-values/invoke-unit)) +(test-syntax-error + "define-values/invoke-unit: expected syntax matching (define-values/invoke-unit (import ...) (export ...))" + (define-values/invoke-unit x y . x)) +(test-syntax-error + "define-values/invoke-unit: expected syntax matching (define-values/invoke-unit (import ...) (export ...))" + (define-values/invoke-unit 1 1)) +(test-syntax-error + "define-values/invoke-unit: expected syntax matching (define-values/invoke-unit (import ...) (export ...))" + (define-values/invoke-unit (unit (import) (export (prefix x: x-sig) x-sig2) + (define x 1) + (define x:x 2)) + x-sig x-sig2)) ;; simple units, compound-units, and invoke-units (no subtypes, no tags, no prefix/rename/etc, no fancy signatures) (test 12 - (invoke-unit (unit (import) (export) 12))) + (invoke-unit (unit (import) (export) 12))) (test 3 - (invoke-unit - (compound-unit (import) (export) - (link (((X : x-sig) (Y : y-sig)) (unit (import empty-sig z-sig) - (export y-sig x-sig) - (define x 1) - (define y 2)) - Z E) - (((Z : z-sig) (E : empty-sig)) (unit (import x-sig y-sig) - (export empty-sig z-sig) - (define z 3) - 3) X Y))))) - + (invoke-unit + (compound-unit (import) (export) + (link (((X : x-sig) (Y : y-sig)) (unit (import empty-sig z-sig) + (export y-sig x-sig) + (define x 1) + (define y 2)) + Z E) + (((Z : z-sig) (E : empty-sig)) (unit (import x-sig y-sig) + (export empty-sig z-sig) + (define z 3) + 3) X Y))))) + ;; Test compound export with signatures containing overlapping names (test (list 10 11 12) - (let ((un (compound-unit (import) (export S U) - (link (((S : x-sig)) (unit (import) (export x-sig) (define x 10))) - (((U : xy-sig)) (unit (import) (export xy-sig) (define x 11) (define y 12))))))) - (invoke-unit - (compound-unit (import) (export) - (link (((S : x-sig) (U : xy-sig)) un) - (((B : b-sig)) (unit (import x-sig) (export b-sig) (define b x)) S) - (() (unit (import b-sig xy-sig) (export) (list b x y)) B U)))))) + (let ((un (compound-unit (import) (export S U) + (link (((S : x-sig)) (unit (import) (export x-sig) (define x 10))) + (((U : xy-sig)) (unit (import) (export xy-sig) (define x 11) (define y 12))))))) + (invoke-unit + (compound-unit (import) (export) + (link (((S : x-sig) (U : xy-sig)) un) + (((B : b-sig)) (unit (import x-sig) (export b-sig) (define b x)) S) + (() (unit (import b-sig xy-sig) (export) (list b x y)) B U)))))) (define-signature even-sig (even)) (define-signature odd-sig (odd)) (define even-unit (unit (import odd-sig) - (export even-sig) + (export even-sig) (define (even x) (or (= 0 x) (odd (sub1 x)))))) (define odd-unit (unit (import even-sig) - (export odd-sig) + (export odd-sig) (define (odd x) (and (> x 0) (even (sub1 x)))) (define x (odd 11)) @@ -368,8 +456,8 @@ (define run-unit (compound-unit (import) (export) - (link (((EVEN : even-sig)) even-unit ODD) - (((ODD : odd-sig)) odd-unit EVEN)))) + (link (((EVEN : even-sig)) even-unit ODD) + (((ODD : odd-sig)) odd-unit EVEN)))) (test #t (invoke-unit run-unit)) @@ -379,38 +467,38 @@ (define is-3x-unit (unit (import is-3x+2-sig) - (export is-3x-sig) + (export is-3x-sig) (define (is-3x x) (or (= 0 x) (is-3x+2 (sub1 x)))))) (define is-3x+2-unit (unit (import is-3x+1-sig) - (export is-3x+2-sig) + (export is-3x+2-sig) (define (is-3x+2 x) (and (> x 0) (is-3x+1 (sub1 x)))))) (define is-3x+1-unit (unit (import is-3x-sig) - (export is-3x+1-sig) + (export is-3x+1-sig) (define (is-3x+1 x) (and (> x 0) (is-3x (sub1 x)))))) (define 3x-compound1 (compound-unit (import (IS-3X : is-3x-sig)) (export IS-3X+1 IS-3X+2) - (link (((IS-3X+1 : is-3x+1-sig)) is-3x+1-unit IS-3X) - (((IS-3X+2 : is-3x+2-sig)) is-3x+2-unit IS-3X+1)))) + (link (((IS-3X+1 : is-3x+1-sig)) is-3x+1-unit IS-3X) + (((IS-3X+2 : is-3x+2-sig)) is-3x+2-unit IS-3X+1)))) (define 3x-compound2 (compound-unit (import) (export IS-3X) - (link (((IS-3X : is-3x-sig)) is-3x-unit IS-3X+2) - (((IS-3X+1 : is-3x+1-sig) - (IS-3X+2 : is-3x+2-sig)) 3x-compound1 IS-3X)))) + (link (((IS-3X : is-3x-sig)) is-3x-unit IS-3X+2) + (((IS-3X+1 : is-3x+1-sig) + (IS-3X+2 : is-3x+2-sig)) 3x-compound1 IS-3X)))) (define 3x-run-unit (unit (import is-3x-sig is-3x+1-sig is-3x+2-sig) - (export) + (export) (list (is-3x 1) (is-3x 3) (is-3x+1 5) @@ -421,100 +509,104 @@ (define 3x-compound3 (compound-unit (import) (export IS-3X IS-3X+1 IS-3X+2) - (link (((IS-3X : is-3x-sig)) 3x-compound2) - (((IS-3X+1 : is-3x+1-sig) - (IS-3X+2 : is-3x+2-sig)) 3x-compound1 IS-3X) - (() 3x-run-unit IS-3X IS-3X+1 IS-3X+2)))) + (link (((IS-3X : is-3x-sig)) 3x-compound2) + (((IS-3X+1 : is-3x+1-sig) + (IS-3X+2 : is-3x+2-sig)) 3x-compound1 IS-3X) + (() 3x-run-unit IS-3X IS-3X+1 IS-3X+2)))) (test (list #f #t #f #t #f #t) - (invoke-unit 3x-compound3)) + (invoke-unit 3x-compound3)) (test (list #t #t #t) - (let () - (define-values/invoke-unit 3x-compound3 (import) (export is-3x-sig is-3x+1-sig is-3x+2-sig)) - (list (is-3x+2 8) - (is-3x+1 7) - (is-3x 6)))) + (let () + (define-values/invoke-unit 3x-compound3 (import) (export is-3x-sig is-3x+1-sig is-3x+2-sig)) + (list (is-3x+2 8) + (is-3x+1 7) + (is-3x 6)))) (test (list #t #t #t) - (let () - (define-values/invoke-unit 3x-compound3 (import) (export (only is-3x-sig is-3x) (except is-3x+1-sig) (prefix x: is-3x+2-sig))) - (list (x:is-3x+2 8) - (is-3x+1 7) - (is-3x 6)))) + (let () + (define-values/invoke-unit 3x-compound3 (import) (export (only is-3x-sig is-3x) (except is-3x+1-sig) (prefix x: is-3x+2-sig))) + (list (x:is-3x+2 8) + (is-3x+1 7) + (is-3x 6)))) (test (list #t #t #t) - (let () - (define-values/invoke-unit 3x-compound3 (import) (export is-3x-sig is-3x+1-sig (rename is-3x+2-sig (y is-3x+2)))) - (list (y 8) - (is-3x+1 7) - (is-3x 6)))) + (let () + (define-values/invoke-unit 3x-compound3 (import) (export is-3x-sig is-3x+1-sig (rename is-3x+2-sig (y is-3x+2)))) + (list (y 8) + (is-3x+1 7) + (is-3x 6)))) ;; Tags (let () (define u (unit (import x-sig (tag t (prefix t: x-sig)) (tag u (prefix u: x-sig))) - (export) - (list x t:x u:x))) + (export) + (list x t:x u:x))) (define v (unit (import) - (export x-sig (tag t (prefix t: x-sig)) (tag u (prefix u: x-sig))) - (define x 1) - (define t:x 2) - (define u:x 3))) + (export x-sig (tag t (prefix t: x-sig)) (tag u (prefix u: x-sig))) + (define x 1) + (define t:x 2) + (define u:x 3))) (test '(3 1 2) - (invoke-unit - (compound-unit (import) (export) - (link (((X1 : x-sig) (X2 : (tag u x-sig)) (X3 : (tag t x-sig))) v) - (() u (tag t X1) X2 (tag u X3)))))) + (invoke-unit + (compound-unit (import) (export) + (link (((X1 : x-sig) (X2 : (tag u x-sig)) (X3 : (tag t x-sig))) v) + (() u (tag t X1) X2 (tag u X3)))))) (test '(3 1 2) - (invoke-unit - (compound-unit (import) (export) - (link (((L1 : (tag a x-sig)) (L2 : (tag b x-sig)) (L3 : (tag c x-sig))) - (compound-unit (import) (export (tag a X1) (tag b X2) (tag c X3)) - (link (((X1 : x-sig) (X2 : (tag u x-sig)) (X3 : (tag t x-sig))) v)))) - (() - (compound-unit (import (X1 : x-sig) (X2 : (tag u x-sig)) (X3 : (tag t x-sig))) (export) - (link (() u (tag t X1) X2 (tag u X3)))) - L1 (tag u L2) (tag t L3))))))) + (invoke-unit + (compound-unit (import) (export) + (link (((L1 : (tag a x-sig)) (L2 : (tag b x-sig)) (L3 : (tag c x-sig))) + (compound-unit (import) (export (tag a X1) (tag b X2) (tag c X3)) + (link (((X1 : x-sig) (X2 : (tag u x-sig)) (X3 : (tag t x-sig))) v)))) + (() + (compound-unit (import (X1 : x-sig) (X2 : (tag u x-sig)) (X3 : (tag t x-sig))) (export) + (link (() u (tag t X1) X2 (tag u X3)))) + L1 (tag u L2) (tag t L3))))))) (let () (define-values/invoke-unit (unit (import) (export (tag t x-sig)) (define x 1)) (import) (export (tag t x-sig))) (test 1 x)) ;; simple runtime errors (no subtyping, no deps) -(test-runtime-error exn:fail:contract? "compound-unit: not a unit" - (compound-unit (import) (export) (link (() 1)))) -(test-runtime-error exn:fail:contract? "compound-unit: missing import" - (compound-unit (import) (export) - (link (() (unit (import x-sig) (export)))))) -(test-runtime-error exn:fail:contract? "compound-unit: missing import" - (compound-unit (import (X : x-sig)) (export) - (link (() (unit (import x-sig) (export)) - (tag u X))))) -(test-runtime-error exn:fail:contract? "compound-unit: missing import" - (compound-unit (import (X : x-sig)) (export) - (link (() (unit (import (tag u x-sig)) (export)) - X)))) -(test-runtime-error exn:fail:contract? "compound-unit: missing export" - (compound-unit (import) (export) - (link (((X : x-sig)) (unit (import) (export)))))) -(test-runtime-error exn:fail:contract? "compound-unit: missing export" - (compound-unit (import) (export) - (link (((X : (tag u x-sig))) (unit (import) (export x-sig) (define x 1)))))) -(test-runtime-error exn:fail:contract? "compound-unit: missing export" - (compound-unit (import) (export) - (link (((X : x-sig)) (unit (import (tag u x-sig)) (export)))))) +(test-runtime-error exn:fail:contract? "compound-unit: result of unit expression was not a unit: 1" + (compound-unit (import) (export) (link (() 1)))) +(test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an untagged import with signature x-sig, which this usage context does not supply" + (compound-unit (import) (export) + (link (() (unit (import x-sig) (export)))))) +(test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an untagged import with signature x-sig, which this usage context does not supply" + (compound-unit (import (X : x-sig)) (export) + (link (() (unit (import x-sig) (export)) + (tag u X))))) +(test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an import for tag u with signature x-sig, which this usage context does not supply" + (compound-unit (import (X : x-sig)) (export) + (link (() (unit (import (tag u x-sig)) (export)) + X)))) +(test-runtime-error exn:fail:contract? "compound-unit: this usage context expects a unit with an untagged export with signature x-sig, which the given unit does not supply" + (compound-unit (import) (export) + (link (((X : x-sig)) (unit (import) (export)))))) +(test-runtime-error exn:fail:contract? "compound-unit: this usage context expects a unit with an export for tag u with signature x-sig, which the given unit does not supply" + (compound-unit (import) (export) + (link (((X : (tag u x-sig))) (unit (import) (export x-sig) (define x 1)))))) +(test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an import for tag u with signature x-sig, which this usage context does not supply" + (compound-unit (import) (export) + (link (((X : x-sig)) (unit (import (tag u x-sig)) (export)))))) -(test-runtime-error exn:fail:contract? "invoke-unit: not a unit" - (invoke-unit 1)) -(test-runtime-error exn:fail:contract? "invoke-unit: unit has imports" - (invoke-unit (unit (import x-sig) (export) x))) +(test-runtime-error exn:fail:contract? "invoke-unit: result of unit expression was not a unit: 1" + (invoke-unit 1)) +(test-runtime-error exn:fail:contract? "invoke-unit: unit argument expects an untagged import with signature x-sig, which this usage context does not supply" + (invoke-unit (unit (import x-sig) (export) x))) -(test-runtime-error exn:fail:contract? "define-values/invoke-unit: not a unit" - (define-values/invoke-unit 1 (import) (export))) -(test-runtime-error exn:fail:contract? "define-values/invoke-unit: has imports" - (define-values/invoke-unit (unit (import x-sig) (export) x) (import) (export))) -(test-runtime-error exn:fail:contract? "define-values/invoke-unit: signature mismatch" - (define-values/invoke-unit (unit (import) (export)) (import) (export x-sig))) +(test-runtime-error exn:fail:contract? "define-values/invoke-unit: result of unit expression was not a unit: 1" + (define-values/invoke-unit 1 (import) (export))) +(test-runtime-error + exn:fail:contract? + "define-values/invoke-unit: unit argument expects an untagged import with signature x-sig, which this usage context does not supply" + (define-values/invoke-unit (unit (import x-sig) (export) x) (import) (export))) +(test-runtime-error + exn:fail:contract? + "define-values/invoke-unit: this usage context expects a unit with an untagged export with signature x-sig, which the given unit does not supply" + (define-values/invoke-unit (unit (import) (export)) (import) (export x-sig))) ;; unit creation w/o signatures (including macros and prefixes/renames). @@ -522,20 +614,20 @@ (let ((y 1) (z 10)) (define u (unit (import) (export yz-sig) - (define y 2) - (define z 3))) + (define y 2) + (define z 3))) (define u1 (unit (import) (export) - y)) + y)) (define u2 (unit (import (only yz-sig z)) (export) - y)) + y)) (define u3 (unit (import (except yz-sig y)) (export) - y)) + y)) (define u4 (unit (import (prefix s: yz-sig)) (export) - y)) + y)) (define u5 (unit (import (rename yz-sig (r y))) (export) - y)) + y)) (define u6 (unit (import yz-sig) (export) - y)) + y)) (define (l x) (invoke-unit (compound-unit (import) (export) @@ -554,85 +646,85 @@ (define-values/invoke-unit (unit-from-context yz-sig) (import) (export yz-sig)) y)) (test 1 - (let () - (let ((u (unit-from-context yz-sig))) - (define-values/invoke-unit u (import) (export (prefix x: yz-sig))) - x:y))) + (let () + (let ((u (unit-from-context yz-sig))) + (define-values/invoke-unit u (import) (export (prefix x: yz-sig))) + x:y))) ;; Exporting and prefix don't work right because the shadower doesn't see the shadowed ;; bindings, I think. #;(test 1 + (let ((x:y 12) + (x:z 10)) +(let ((u (unit-from-context (prefix x: yz-sig)))) + (define-values/invoke-unit u yz-sig) + y))) +#;(test 1 +(let ((x:y 12) + (x:z 10)) + (define-signature t (y z)) + (let ((u (unit-from-context (prefix x: t)))) + (define-values/invoke-unit u t) + y))) +(test 12 (let ((x:y 12) (x:z 10)) - (let ((u (unit-from-context (prefix x: yz-sig)))) - (define-values/invoke-unit u yz-sig) - y))) - #;(test 1 - (let ((x:y 12) - (x:z 10)) - (define-signature t (y z)) - (let ((u (unit-from-context (prefix x: t)))) - (define-values/invoke-unit u t) - y))) - (test 12 - (let ((x:y 12) - (x:z 10)) - (define-values/invoke-unit (unit-from-context (rename yz-sig (x:y y) (x:z z))) - (import) (export yz-sig)) - y)) - (test 12 - (let ((x:y 12) - (x:z 10)) - (define-signature t (y z)) - (let () - (define-values/invoke-unit (unit-from-context (rename t (x:y y) (x:z z))) (import) (export t)) - y)))) + (define-values/invoke-unit (unit-from-context (rename yz-sig (x:y y) (x:z z))) + (import) (export yz-sig)) + y)) +(test 12 + (let ((x:y 12) + (x:z 10)) + (define-signature t (y z)) + (let () + (define-values/invoke-unit (unit-from-context (rename t (x:y y) (x:z z))) (import) (export t)) + y)))) ;; Test that a define-values can define both internal and exported vars (test '(1 2) - (invoke-unit - (compound-unit (import) (export) - (link (((T : yz-sig)) (unit (import x-sig) (export yz-sig) + (invoke-unit + (compound-unit (import) (export) + (link (((T : yz-sig)) (unit (import x-sig) (export yz-sig) (define-values (y a) (values 1 2)) (define-values (b z) (values y a))) - S) - (((S : x-sig)) (unit (import yz-sig) (export x-sig) (define x 3) (list y z)) T))))) + S) + (((S : x-sig)) (unit (import yz-sig) (export x-sig) (define x 3) (list y z)) T))))) ;; Test that internal macros can define exports (test 1 - (invoke-unit - (unit (import) (export x-sig) + (invoke-unit + (unit (import) (export x-sig) (define-syntax (y stx) (syntax-case stx () ((_ x) #'(define x 1)))) (y x) x))) - + (define-signature fact-sig (fact n)) ;; Test renaming, self-recursion, only, and except (test 24 - (invoke-unit - (compound-unit (import) (export) - (link (((F : fact-sig)) (unit (import (except (rename fact-sig (f-in fact)) n)) - (export (rename fact-sig (f-out fact))) - (define n 1) - (define (f-out x) (if (= 0 x) - 1 - (* x (f-in (sub1 x)))))) + (invoke-unit + (compound-unit (import) (export) + (link (((F : fact-sig)) (unit (import (except (rename fact-sig (f-in fact)) n)) + (export (rename fact-sig (f-out fact))) + (define n 1) + (define (f-out x) (if (= 0 x) + 1 + (* x (f-in (sub1 x)))))) F) - (() (unit (import (only fact-sig fact)) (export) - (define n 2) - (fact 4)) - F))))) + (() (unit (import (only fact-sig fact)) (export) + (define n 2) + (fact 4)) + F))))) ;; Test import prefix (test 1 - (invoke-unit - (compound-unit (import) (export) - (link (((S : x-sig)) (unit (import) (export x-sig) (define x 1))) - (() (unit (import (prefix s: x-sig)) (export) s:x) S))))) + (invoke-unit + (compound-unit (import) (export) + (link (((S : x-sig)) (unit (import) (export x-sig) (define x 1))) + (() (unit (import (prefix s: x-sig)) (export) s:x) S))))) (define-signature sx (x)) (define-signature sy (y)) @@ -640,50 +732,50 @@ ;; Test separate signatures with overlapping bindings, and export renaming and prefix (test '(1 2 3) - (invoke-unit - (compound-unit (import) (export) - (link (((S : x-sig) (T : yz-sig) (U : xy-sig)) (unit (import) (export (rename x-sig (s:x x)) - (rename yz-sig (t:y y) (t:z z)) - (prefix u: xy-sig)) - (define x 1) (define y 2) (define z 3) - (define s:x x) (define t:y y) (define t:z z) (define u:x x) (define u:y y))) - (((SX : sx)) (unit (import (prefix s: x-sig)) (export sx) (define x s:x)) S) - (((SY : sy)) (unit (import (prefix u: xy-sig)) (export sy) (define y u:y)) U) - (((SZ : sz)) (unit (import (prefix t: yz-sig)) (export sz) (define z t:z)) T) - (() (unit (import sx sy sz) (export) (list x y z)) SX SY SZ))))) + (invoke-unit + (compound-unit (import) (export) + (link (((S : x-sig) (T : yz-sig) (U : xy-sig)) (unit (import) (export (rename x-sig (s:x x)) + (rename yz-sig (t:y y) (t:z z)) + (prefix u: xy-sig)) + (define x 1) (define y 2) (define z 3) + (define s:x x) (define t:y y) (define t:z z) (define u:x x) (define u:y y))) + (((SX : sx)) (unit (import (prefix s: x-sig)) (export sx) (define x s:x)) S) + (((SY : sy)) (unit (import (prefix u: xy-sig)) (export sy) (define y u:y)) U) + (((SZ : sz)) (unit (import (prefix t: yz-sig)) (export sz) (define z t:z)) T) + (() (unit (import sx sy sz) (export) (list x y z)) SX SY SZ))))) ;; Test units importing and exporting b, where lexical definition of b shadows ;; the b identifier in the signature (test 2 - (let ((b 1)) - (define u1 (unit (import) (export b-sig) (define b 2))) - (define u2 (unit (import b-sig) (export) b)) - (invoke-unit (compound-unit (import) (export) - (link (((B : b-sig)) u1) - (() u2 B)))))) + (let ((b 1)) + (define u1 (unit (import) (export b-sig) (define b 2))) + (define u2 (unit (import b-sig) (export) b)) + (invoke-unit (compound-unit (import) (export) + (link (((B : b-sig)) u1) + (() u2 B)))))) (test 1 - (let ((b 1)) - (define u1 (unit-from-context b-sig)) - (let ((b 2)) - (define-values/invoke-unit u1 (import) (export b-sig)) - b))) + (let ((b 1)) + (define u1 (unit-from-context b-sig)) + (let ((b 2)) + (define-values/invoke-unit u1 (import) (export b-sig)) + b))) (let ((x 1) (v 2)) (let-syntax ((s (syntax-rules () ((_) (list x v))))) (define-signature t (x (define-syntaxes (s) - (syntax-rules () - ((_) (list x v)))) + (syntax-rules () + ((_) (list x v)))) (define-values (v) (add1 x)))) (define-signature t2 (x (define-syntaxes (s) - (syntax-rules () - ((_) (list x v)))) - (define-values (v) (add1 x)))) + (syntax-rules () + ((_) (list x v)))) + (define-values (v) (add1 x)))) (define u3 (unit (import) (export t) - (define x 3))) + (define x 3))) (define u4 (unit (import) (export t2) - (define x 4))) + (define x 4))) (define (i u) (invoke-unit (compound-unit (import) (export) @@ -695,73 +787,73 @@ (v 6)) (let-syntax ((s (syntax-rules () ((_) (list x v))))) (test '(7 8 (7 8) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (prefix p: t) (prefix q: t2)) (export) + (i (unit (import (prefix p: t) (prefix q: t2)) (export) (define x 7) (define v 8) (define-syntax s (syntax-rules () ((_) (list x v)))) (list x v (s) p:x p:v (p:s) q:x q:v (q:s))))) (test '(5 6 (5 6) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (prefix p: t) (prefix q: t2)) (export) + (i (unit (import (prefix p: t) (prefix q: t2)) (export) (list x v (s) p:x p:v (p:s) q:x q:v (q:s))))))) (test '(7 8 (7 8) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (prefix p: t) (prefix q: t2)) (export) + (i (unit (import (prefix p: t) (prefix q: t2)) (export) (define x 7) (define v 8) (define-syntax s (syntax-rules () ((_) (list x v)))) (list x v (s) p:x p:v (p:s) q:x q:v (q:s))))) (test '(1 2 (1 2) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (prefix p: t) (prefix q: t2)) (export) + (i (unit (import (prefix p: t) (prefix q: t2)) (export) (list x v (s) p:x p:v (p:s) q:x q:v (q:s))))) ;; only (let ((x 5) (v 6)) (let-syntax ((s (syntax-rules () ((_) (list x v))))) (test '(7 8 (7 8) (3 4) (4 5)) - (i (unit (import (prefix p: (only t s)) (only (prefix q: t2) q:s)) (export) + (i (unit (import (prefix p: (only t s)) (only (prefix q: t2) q:s)) (export) (define x 7) (define v 8) (define-syntax s (syntax-rules () ((_) (list x v)))) (list x v (s) (p:s) (q:s))))) (test '(5 6 (5 6) (3 4) (4 5)) - (i (unit (import (prefix p: (only t s)) (prefix q: (only t2 s))) (export) + (i (unit (import (prefix p: (only t s)) (prefix q: (only t2 s))) (export) (list x v (s) (p:s) (q:s))))))) (test '(7 8 (7 8) (3 4) (4 5)) - (i (unit (import (only (prefix p: t) p:s) (only (prefix q: t2) q:s)) (export) + (i (unit (import (only (prefix p: t) p:s) (only (prefix q: t2) q:s)) (export) (define x 7) (define v 8) (define-syntax s (syntax-rules () ((_) (list x v)))) (list x v (s) (p:s) (q:s))))) (test '(1 2 (1 2) (3 4) (4 5)) - (i (unit (import (prefix p: (only t s)) (prefix q: (only t2 s))) (export) + (i (unit (import (prefix p: (only t s)) (prefix q: (only t2 s))) (export) (list x v (s) (p:s) (q:s))))) ;;rename (let ((x 5) (v 6)) (let-syntax ((s (syntax-rules () ((_) (list x v))))) (test '(7 8 (7 8) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) - (rename t2 (q:x x) (q:v v) (q:s s))) + (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) + (rename t2 (q:x x) (q:v v) (q:s s))) (export) (define x 7) (define v 8) (define-syntax s (syntax-rules () ((_) (list x v)))) (list x v (s) p:x p:v (p:s) q:x q:v (q:s))))) (test '(5 6 (5 6) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) - (rename t2 (q:x x) (q:v v) (q:s s))) + (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) + (rename t2 (q:x x) (q:v v) (q:s s))) (export) (list x v (s) p:x p:v (p:s) q:x q:v (q:s))))))) (test '(7 8 (7 8) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) - (rename t2 (q:x x) (q:v v) (q:s s))) + (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) + (rename t2 (q:x x) (q:v v) (q:s s))) (export) (define x 7) (define v 8) (define-syntax s (syntax-rules () ((_) (list x v)))) (list x v (s) p:x p:v (p:s) q:x q:v (q:s))))) (test '(1 2 (1 2) 3 4 (3 4) 4 5 (4 5)) - (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) - (rename t2 (q:x x) (q:v v) (q:s s))) + (i (unit (import (rename t (p:x x) (p:v v) (p:s s)) + (rename t2 (q:x x) (q:v v) (q:s s))) (export) (list x v (s) p:x p:v (p:s) q:x q:v (q:s)))))) ) @@ -777,10 +869,10 @@ (m a) (a 1))))) (test 1 - (invoke-unit - (compound-unit (import) (export) - (link (((X : x)) (unit (import) (export x))) - (() (unit (import x) (export) v) X)))))) + (invoke-unit + (compound-unit (import) (export) + (link (((X : x)) (unit (import) (export x))) + (() (unit (import x) (export) v) X)))))) (let () (define-signature x ((define-syntaxes (m) (syntax-rules () @@ -794,10 +886,10 @@ (m a) (m2 a))))) (test 1 - (invoke-unit - (compound-unit (import) (export) - (link (((X : x)) (unit (import) (export x))) - (() (unit (import x) (export) v) X)))))) + (invoke-unit + (compound-unit (import) (export) + (link (((X : x)) (unit (import) (export x))) + (() (unit (import x) (export) v) X)))))) (let () (define-signature x ((define-syntaxes (m) #'1) @@ -809,10 +901,10 @@ (let () (m2 m))))) (test 1 - (invoke-unit - (compound-unit (import) (export) - (link (((X : x)) (unit (import) (export x))) - (() (unit (import x) (export) v) X)))))) + (invoke-unit + (compound-unit (import) (export) + (link (((X : x)) (unit (import) (export x))) + (() (unit (import x) (export) v) X)))))) (let () @@ -821,8 +913,8 @@ (define u1 (unit (import s2) (export) (cons y z))) (define u2 (unit (import) (export s2) (define a 123))) (test (list 2 123 1) (invoke-unit (compound-unit (import) (export) - (link (((a : s2)) u2) - (() u1 a)))))) + (link (((a : s2)) u2) + (() u1 a)))))) (let () (define-signature s1 (a (define-values (x y) (values 1 2)))) (let ((x 12)) @@ -838,8 +930,8 @@ (define u1 (unit (import s2) (export) (define c 77) (cons y z))) (define u2 (unit (import) (export s2) (define a 123))) (test (list 2 123 50) (invoke-unit (compound-unit (import) (export) - (link (((a : s2)) u2) - (() u1 a)))))) + (link (((a : s2)) u2) + (() u1 a)))))) #; (let ([c 5]) (define-signature s1 (a (define-values (x y) (values c 2)))) @@ -850,96 +942,96 @@ (link (((a : s2)) u2) (() u1 a)))))) -;; Test define-syntaxes and define-values, without except, only, prefix and rename -;; Check the scoping -(let ((a 'abad) - (b 'bbad) - (c 'cbad) - (v1 'v1bad) - (v2 'v2bad) - (s1 's1bad) - (s2 's2bad) - (strange-fact 'sfbad) - (z 'zbad)) - (define z 1) - (define a 'abad2) - (define c 'cbad2) - (define strange-fact 'sfbad4) - (define-signature macro (a b c - (define-values (v1) (list a b c z 2)) - (define-values (v2) (s2 a b c)) - (define-values (strange-fact) - (lambda (x) - (if (= x 0) (list z a b c) (cons x (strange-fact (sub1 x)))))) - (define-syntaxes (s1 s2) - (values - (syntax-rules () - ((_ a1 b1 c1) (list a b c v1 a1 b1 c1 z))) - (syntax-rules () - ((_ a1 b1 c1) (s1 a1 b1 c1))))))) - (let ((b 'bbad2) - (c 'cbad3)) - (define z 3) - (define u1 - (unit (import macro) (export) - (define z 4) - (list a b c v1 v2 (strange-fact 5) (s1 6 7 8) (s2 9 10 11)))) - (define u2 - (unit (import) (export macro) - (define a 12) - (define b 13) - (define c 14))) - (test '(12 13 14 - (12 13 14 1 2) - (12 13 14 (12 13 14 1 2) 12 13 14 1) - (5 4 3 2 1 1 12 13 14) - (12 13 14 (12 13 14 1 2) 6 7 8 1) - (12 13 14 (12 13 14 1 2) 9 10 11 1)) - (invoke-unit - (compound-unit (import) (export) - (link (((U2 : macro)) u2) - (() u1 U2))))))) + ;; Test define-syntaxes and define-values, without except, only, prefix and rename + ;; Check the scoping + (let ((a 'abad) + (b 'bbad) + (c 'cbad) + (v1 'v1bad) + (v2 'v2bad) + (s1 's1bad) + (s2 's2bad) + (strange-fact 'sfbad) + (z 'zbad)) + (define z 1) + (define a 'abad2) + (define c 'cbad2) + (define strange-fact 'sfbad4) + (define-signature macro (a b c + (define-values (v1) (list a b c z 2)) + (define-values (v2) (s2 a b c)) + (define-values (strange-fact) + (lambda (x) + (if (= x 0) (list z a b c) (cons x (strange-fact (sub1 x)))))) + (define-syntaxes (s1 s2) + (values + (syntax-rules () + ((_ a1 b1 c1) (list a b c v1 a1 b1 c1 z))) + (syntax-rules () + ((_ a1 b1 c1) (s1 a1 b1 c1))))))) + (let ((b 'bbad2) + (c 'cbad3)) + (define z 3) + (define u1 + (unit (import macro) (export) + (define z 4) + (list a b c v1 v2 (strange-fact 5) (s1 6 7 8) (s2 9 10 11)))) + (define u2 + (unit (import) (export macro) + (define a 12) + (define b 13) + (define c 14))) + (test '(12 13 14 + (12 13 14 1 2) + (12 13 14 (12 13 14 1 2) 12 13 14 1) + (5 4 3 2 1 1 12 13 14) + (12 13 14 (12 13 14 1 2) 6 7 8 1) + (12 13 14 (12 13 14 1 2) 9 10 11 1)) + (invoke-unit + (compound-unit (import) (export) + (link (((U2 : macro)) u2) + (() u1 U2))))))) -;; We can re-define imported values -(let () - (define-signature s ((define-values (y) 1))) - (define-signature t (z)) + ;; We can re-define imported values + (let () + (define-signature s ((define-values (y) 1))) + (define-signature t (z)) (test 3 - (invoke-unit - (compound-unit (import) (export) - (link (((T : t)) (unit (import s) (export t) (define y 3) (define z y)) S) - (((S : s)) (unit (import) (export s) (define y 1))) - (() (unit (import t) (export) z) T)))))) + (invoke-unit + (compound-unit (import) (export) + (link (((T : t)) (unit (import s) (export t) (define y 3) (define z y)) S) + (((S : s)) (unit (import) (export s) (define y 1))) + (() (unit (import t) (export) z) T)))))) -;; Can't use imports as pattern variables -#;(let () + ;; Can't use imports as pattern variables + #;(let () (define-signature s (y (define-syntaxes (m) (syntax-rules (y) ((_ y) 1))))) (unit (import s) (export) - (m y))) + (m y))) -(test '(2 3) + (test '(2 3) + (let () + (define-signature sig (y (define-values (v) (add1 y)))) + (let () + (define-values/invoke-unit + (unit (import) (export sig) (define y 2)) + (import) + (export sig)) + (list y v)))) + + + ;; I'm not sure that this should work. + #;(test '(2 3) (let () - (define-signature sig (y (define-values (v) (add1 y)))) - (let () - (define-values/invoke-unit - (unit (import) (export sig) (define y 2)) - (import) - (export sig)) - (list y v)))) + (define-signature sig (y (define-values (v) (add1 y)))) + (define-values/invoke-unit + (unit (import) (export sig) (define y 2)) + sig) + (list y v))) -;; I'm not sure that this should work. -#;(test '(2 3) - (let () - (define-signature sig (y (define-values (v) (add1 y)))) - (define-values/invoke-unit - (unit (import) (export sig) (define y 2)) - sig) - (list y v))) - - ;; subtyping @@ -985,16 +1077,16 @@ (define u1 (unit (import) (export x-sig) (define x 1))) (define u2 (unit (import x-sub) (export))) - (test-runtime-error exn:fail:contract? "compound-unit: not a subtype" + (test-runtime-error exn:fail:contract? "compound-unit: this usage context expects a unit with an untagged export with signature x-sub, which the given unit does not supply" (compound-unit (import) (export) (link (((S : x-sub)) u1)))) - (test-runtime-error exn:fail:contract? "compound-unit: not a subtype" + (test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an untagged import with signature x-sub, which this usage context does not supply" (compound-unit (import) (export) (link (((S : x-sig)) u1) (() u2 S)))) - (test-runtime-error exn:fail:contract? "compound-unit: not a subtype" + (test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an untagged import with signature x-sub, which this usage context does not supply" (compound-unit (import (S : x-sig)) (export) (link (() u2 S))))) @@ -1002,43 +1094,46 @@ (define u1 (unit (import) (export x-sub y-sub) (define x 1) (define xx 2) (define y 3) (define yy 4))) (define-values/invoke-unit u1 (import) (export x-sig)) (test 1 x) - (test-runtime-error exn? "unbound identifier" xx) - (test-runtime-error exn? "unbound identifier" y) - (test-runtime-error exn? "unbound identifier" yy)) + (test-runtime-error exn? "xx: undefined;\n cannot reference undefined identifier" xx) + (test-runtime-error exn? "y: undefined;\n cannot reference undefined identifier" y) + (test-runtime-error exn? "yy: undefined;\n cannot reference undefined identifier" yy)) (let () (define u1 (unit (import) (export x-sig) (define x 1))) - (test-runtime-error exn:fail:contract? "define-values/invoke-unit: not a subtype" + (test-runtime-error exn:fail:contract? "define-values/invoke-unit: this usage context expects a unit with an untagged export with signature x-sub, which the given unit does not supply" (define-values/invoke-unit u1 (import) (export x-sub)))) ;; export-subtyping -(test-syntax-error "duplicate exports (subtypes)" - (unit (import) (export x-sig x-sub) - (define x 1) - (define xx 1))) -(test-syntax-error "duplicate exports (subtypes)" - (unit (import) (export x-sub x-sig) - (define x 1) - (define xx 1))) +(test-syntax-error + "unit: the signature of x-sub extends this signature" + (unit (import) (export x-sig x-sub) + (define x 1) + (define xx 1))) +(test-syntax-error + "unit: the signature of x-sub extends this signature" + (unit (import) (export x-sub x-sig) + (define x 1) + (define xx 1))) (let () (define u (unit (import) (export x-sub) (define x 1) (define xx 1))) - (test-syntax-error "duplicate exports (subtypes)" - (compound-unit (import) (export l1 l2) - (link (((l1 : s1)) u) - (((l2 : s2)) u))))) + (test-syntax-error + "compound-unit: unknown signature" + (compound-unit (import) (export l1 l2) + (link (((l1 : s1)) u) + (((l2 : s2)) u))))) (let () (define u (unit (import) (export x-sub (prefix x: x-sub2)) - (define x 1) - (define xx 2) - (define x:x 3) - (define x:x2 4))) + (define x 1) + (define xx 2) + (define x:x 3) + (define x:x2 4))) (define u2 (unit (import x-sig) (export))) (define v (unit (import x-sub) (export) - (+ x xx))) + (+ x xx))) (define w (unit (import x-sub2) (export) - (+ x x2))) + (+ x x2))) (define u3 (unit (import x-sub (prefix m: x-sub2)) (export) - (+ x xx m:x m:x2))) + (+ x xx m:x m:x2))) (test 3 (invoke-unit (compound-unit (import) (export) @@ -1054,18 +1149,20 @@ (compound-unit (import) (export) (link (((S3 : x-sub2) (S2 : x-sub)) u) (() u3 S3 S2))))) - (test-runtime-error exn:fail:contract? "ambiguous export" + (test-runtime-error exn:fail:contract? + "compound-unit: this usage context expects a unit with an untagged export with signature x-sig, which the given unit supplies multiple times" (compound-unit (import) (export) - (link (((S1 : x-sig)) u))))) - (test-runtime-error exn:fail:contract? "ambiguous import" + (link (((S1 : x-sig)) u)))) + (test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an untagged import with signature x-sig, which this usage context supplies multiple times" (compound-unit (import (S1 : x-sub) (S2 : x-sub2)) (export) (link (() u2 S1 S2)))) -(test-syntax-error "duplicate links (subtype)" - (compound-unit (import) (export) - (link (((S1 : x-sig)) u3) - (() u1 S2 S1) - (((S2 : x-sig)) u3)))) + (test-syntax-error + "compound-unit: the signature of S2 extends this signature" + (compound-unit (import) (export) + (link (((S1 : x-sig)) u3) + (() u1 S2 S1) + (((S2 : x-sig)) u3))))) ;; tags (let () @@ -1078,44 +1175,44 @@ (tag t (prefix s2: s2)) (prefix bs1: s2) (prefix bs2: s3)) - (export) - (list s1:a s2:a s2:b bs1:a bs2:b))) + (export) + (list s1:a s2:a s2:b bs1:a bs2:b))) (define u2 (unit (import) (export s3) - (define a 1) (define b 2))) + (define a 1) (define b 2))) (define u3 (unit (import) (export s2) - (define a 3) (define b 4))) + (define a 3) (define b 4))) (test '(1 3 4 1 2) (invoke-unit (compound-unit (import) (export) (link (((S2a : s3)) u2) (((S2b : s2)) u3) (() u1 S2a (tag t S2b)))))) - (test-runtime-error exn:fail:contract? "compound-unit: signature mismatch" - (invoke-unit - (compound-unit (import) (export) - (link (((S1 : s1)) u2) - (((S2 : s2)) u3) - (() u1 (tag t S1) S2)))))) + (test-runtime-error exn:fail:contract? "compound-unit: unit argument expects an untagged import with signature s3, which this usage context does not supply" + (invoke-unit + (compound-unit (import) (export) + (link (((S1 : s1)) u2) + (((S2 : s2)) u3) + (() u1 (tag t S1) S2)))))) (let () (define u1 (unit (import) (export (prefix a: x-sig) (tag t (prefix c: x-sig))) - (define a:x 1) - (define c:x 4))) + (define a:x 1) + (define c:x 4))) (define u2 (unit (import x-sig) (export) - x)) + x)) (define u3 (unit (import x-sub) (export) - (list x xx))) + (list x xx))) (test 4 (invoke-unit (compound-unit (import) (export) (link (((S1 : (tag t x-sig)) (S2 : x-sig)) u1) (() u2 S1))))) - (test-runtime-error exn:fail:contract? "compound-unit: signature mismatch" + (test-runtime-error exn:fail:contract? "compound-unit: this usage context expects a unit with an untagged export with signature x-sub, which the given unit does not supply" (invoke-unit (compound-unit (import) (export) (link (((S1 : (tag t x-sub)) (S2 : x-sub)) u1) @@ -1124,8 +1221,8 @@ (let () (define u1 (unit (import) (export (tag t1 x-sig) (prefix : x-sig)) - (define x 10) - (define :x 11))) + (define x 10) + (define :x 11))) (define-values/invoke-unit u1 (import) (export x-sig (tag t1 (prefix m x-sig)))) (test '(11 10) (list x mx))) @@ -1135,90 +1232,152 @@ (define-signature s2 (a x z)) -(test-syntax-error "unit-from-context: no sigs" - (unit-from-context)) -(test-syntax-error "unit-from-context: too many sigs" - (unit-from-context s1 s2)) -(test-syntax-error "unit-from-context: too many sigs" - (unit-from-context s1 . s2)) -(test-syntax-error "unit-from-context: bad sig" - (unit-from-context 1)) +(test-syntax-error + "unit-from-context: missing export-spec" + (unit-from-context)) +(test-syntax-error + "unit-from-context: nothing is permitted after export-spec" + (unit-from-context s1 s2)) +(test-syntax-error + "unit-from-context: nothing is permitted after export-spec" + (unit-from-context s1 . s2)) +(test-syntax-error + "unit-from-context: bad export spec" + (unit-from-context 1)) -(test-syntax-error "unit-from-context: no name" - (define-unit-from-context)) -(test-syntax-error "unit-from-context: no sigs" - (define-unit-from-context s1)) -(test-syntax-error "unit-from-context: no sigs" - (define-unit-from-context n)) -(test-syntax-error "unit-from-context: too many sigs" - (define-unit-from-context n s1 s2)) -(test-syntax-error "unit-from-context: too many sigs" - (define-unit-from-context n s1 . s2)) -(test-syntax-error "unit-from-context: bad sig" - (define-unit-from-context n 1)) +(test-syntax-error + "define-unit-from-context: missing unit name and signature" + (define-unit-from-context)) +(test-syntax-error + "define-unit-from-context: missing export-spec" + (define-unit-from-context s1)) +(test-syntax-error + "define-unit-from-context: missing export-spec" + (define-unit-from-context n)) +(test-syntax-error + "define-unit-from-context: nothing is permitted after export-spec" + (define-unit-from-context n s1 s2)) +(test-syntax-error + "define-unit-from-context: nothing is permitted after export-spec" + (define-unit-from-context n s1 . s2)) +(test-syntax-error + "define-unit-from-context: bad export spec" + (define-unit-from-context n 1)) ;; Test the struct form (test-syntax-error "struct: missing name and fields" - (define-signature x ((struct)))) -(test-syntax-error "struct: missing name" - (define-signature x ((struct n)))) -(test-syntax-error "struct: bad name" - (define-signature x ((struct 1 ())))) -(test-syntax-error "struct: bad fields (dot)" - (define-signature x ((struct n (x . y))))) -(test-syntax-error "struct: bad fields" - (define-signature x ((struct n 1)))) -(test-syntax-error "struct: bad omission" - (define-signature x ((struct n () t)))) -(test-syntax-error "struct: bad omission (dot)" - (define-signature x ((struct n () . -selectors)))) -(test-syntax-error "struct: bad omission" - (define-signature x ((struct n () x)))) + (define-signature x ((struct)))) +(test-syntax-error + "struct: bad syntax; missing fields" + (define-signature x ((struct n)))) +(test-syntax-error + "struct: expected an identifier to name the structure type" + (define-signature x ((struct 1 ())))) +(test-syntax-error + "struct: bad syntax; expected a parenthesized sequence of fields" + (define-signature x ((struct n (x . y))))) +(test-syntax-error + "struct: bad syntax; expected a parenthesized sequence of fields" + (define-signature x ((struct n 1)))) +(test-syntax-error + "struct: expected a keyword to specify option: #:mutable, #:constructor-name, #:extra-constructor-name, #:omit-constructor, #:omit-define-syntaxes, or #:omit-define-values" + (define-signature x ((struct n () t)))) +(test-syntax-error + "struct: bad syntax" + (define-signature x ((struct n () . -selectors)))) +(test-syntax-error + "struct: expected a keyword to specify option: #:mutable, #:constructor-name, #:extra-constructor-name, #:omit-constructor, #:omit-define-syntaxes, or #:omit-define-values" + (define-signature x ((struct n () x)))) (let () (define-signature sig ((struct s (x y)))) (test 3 - (invoke-unit - (compound-unit (import) (export) - (link (((S : sig)) (unit (import) (export sig) + (invoke-unit + (compound-unit (import) (export) + (link (((S : sig)) (unit (import) (export sig) (define-struct s (x y)))) - (() (unit (import sig) (export) - (match (make-s 1 2) + (() (unit (import sig) (export) + (match (s 1 2) ((struct s (a b)) (+ a b)))) - S))))) + S))))) (let () (define-values/invoke-unit (unit (import) (export sig) (define-struct s (x y))) (import) (export sig)) (test 3 - (match (make-s 1 2) - ((struct s (a b)) (+ a b))))) + (match (s 1 2) + ((struct s (a b)) (+ a b))))) + (let () + (define u + (unit (import) (export (rename sig (make-s/defaults s))) + (define-struct s (x y)) + (define (make-s/defaults x) + (make-s x 'default)))) + (define-values/invoke-unit u (import) (export sig)) + (test #t (s? (s 1)))) + + (let ((set-s-x! 1)) + (define-signature sig ((struct s (x y)))) + (test 1 + (invoke-unit + (compound-unit (import) (export) + (link (((S : sig)) (unit (import) (export sig) (define-struct s (x y)))) + (() (unit (import sig) (export) + set-s-x!) S)))))) + ;; TODO: Pending bug fix in units + #;(let ((s 1)) + (define-signature sig ((struct s (x y) #:omit-constructor))) + (test 1 + (invoke-unit + (compound-unit (import) (export) + (link (((S : sig)) (unit (import) (export sig) (define-struct s (x y)))) + (() (unit (import sig) (export) + s) S))))))) +(let () + (local-require scheme/unit) + (define-signature sig ((struct s (x y)))) + (test 3 + (invoke-unit + (compound-unit (import) (export) + (link (((S : sig)) (unit (import) (export sig) + (define-struct s (x y)))) + (() (unit (import sig) (export) + (match (make-s 1 2) + ((struct s (a b)) (+ a b)))) + S))))) + (let () + (define-values/invoke-unit (unit (import) (export sig) (define-struct s (x y))) + (import) + (export sig)) + (test 3 + (match (make-s 1 2) + ((struct s (a b)) (+ a b))))) (let () (define u (unit (import) (export (rename sig (make-s/defaults make-s))) - (define-struct s (x y)) - (define (make-s/defaults x) - (make-s x 'default)))) + (define-struct s (x y)) + (define (make-s/defaults x) + (make-s x 'default)))) (define-values/invoke-unit u (import) (export sig)) (test #t (s? (make-s 1)))) (let ((set-s-x! 1)) (define-signature sig ((struct s (x y)))) (test 1 - (invoke-unit - (compound-unit (import) (export) - (link (((S : sig)) (unit (import) (export sig) (define-struct s (x y)))) - (() (unit (import sig) (export) + (invoke-unit + (compound-unit (import) (export) + (link (((S : sig)) (unit (import) (export sig) (define-struct s (x y)))) + (() (unit (import sig) (export) set-s-x!) S)))))) (let ((make-s 1)) (define-signature sig ((struct s (x y) #:omit-constructor))) (test 1 - (invoke-unit - (compound-unit (import) (export) - (link (((S : sig)) (unit (import) (export sig) (define-struct s (x y)))) - (() (unit (import sig) (export) + (invoke-unit + (compound-unit (import) (export) + (link (((S : sig)) (unit (import) (export sig) (define-struct s (x y)))) + (() (unit (import sig) (export) make-s) S))))))) ;; Dependencies @@ -1227,41 +1386,43 @@ (define-signature s2 extends s1 ()) (define u1 (unit (import s1) (export) (init-depend s1) - a)) + a)) (define u2 (unit (import) (export s1) - (define a 12))) + (define a 12))) (define u3 (unit (import (tag t s1)) (export) (init-depend (tag t s1)) - a)) + a)) (define u4 (compound-unit (import (L : s2)) (export) (link (() u1 L)))) (define u5 (unit (import) (export s2) - (define a 12))) -(test-syntax-error "unit: bad dependency" - (unit (import (tag t s1)) (export) (init-depend s1))) -(test-syntax-error "unit: bad dependency" - (unit (import s1) (export) (init-depend (tag t s1)))) + (define a 12))) +(test-syntax-error + "unit: initialization dependency on unknown import" + (unit (import (tag t s1)) (export) (init-depend s1))) +(test-syntax-error + "unit: initialization dependency on unknown import" + (unit (import s1) (export) (init-depend (tag t s1)))) (test 12 (invoke-unit (compound-unit (import) (export) (link (((S1 : s1)) u2) (() u1 S1))))) -(test-runtime-error exn:fail:contract? "Dependency violation" +(test-runtime-error exn:fail:contract? "compound-unit: untagged initialization dependent signature s1 is supplied from a later unit with link S1" (compound-unit (import) (export) - (link (() u1 S1) - (((S1 : s1)) u2)))) + (link (() u1 S1) + (((S1 : s1)) u2)))) -(test-runtime-error exn:fail:contract? "Dependency violation" +(test-runtime-error exn:fail:contract? "compound-unit: initialization dependent signature s1 with tag t is supplied from a later unit with link S1" (compound-unit (import) (export) - (link (() u3 (tag t S1)) - (((S1 : s1)) u2)))) + (link (() u3 (tag t S1)) + (((S1 : s1)) u2)))) -(test-runtime-error exn:fail:contract? "Dependency violation" +(test-runtime-error exn:fail:contract? "compound-unit: untagged initialization dependent signature s1 is supplied from a later unit with link S2" (compound-unit (import) (export) - (link (() u4 S2) - (((S2 : s2)) u5)))) + (link (() u4 S2) + (((S2 : s2)) u5)))) ;; Inference @@ -1276,119 +1437,144 @@ (link (((A : x-sig) (B : y-sig)) v) (() u A B)))))) -(test-runtime-error exn:fail:contract? "not subunit" +(test-runtime-error exn:fail:contract? "define-unit-binding: this usage context expects a unit with an untagged export with signature x-sig, which the given unit does not supply" (let () (define-unit-binding u2 u (import x-sig) (export x-sig)) 1)) -(test-runtime-error exn:fail:contract? "not subunit" +(test-runtime-error exn:fail:contract? "define-unit-binding: unit argument expects an untagged import with signature x-sig, which this usage context does not supply" (let () (define-unit-binding u2 u (import) (export)) 1)) (test-runtime-error exn:fail:contract? "not a unit" (let () (define-unit-binding u2 1 (import) (export)) 1)) (test-syntax-error "define-unit-binding: duplicate import" (define-unit-binding u 1 (import x-sig x-sig) (export))) -(test-syntax-error "define-unit-binding: export subtypes" - (define-unit-binding u 1 (import) (export x-sig x-sub))) -(test-syntax-error "define-unit-binding: export subtypes" - (define-unit-binding u 1 (import) (export x-sub x-sig))) -(test-syntax-error "define-unit-binding: bad dependency" - (define-unit-binding u 1 (import x-sig) (export) (init-depend x-sub))) -(test-syntax-error "define-unit-binding: bad dependency" - (define-unit-binding u 1 (import x-sub) (export) (init-depend x-sig))) +(test-syntax-error + "define-unit-binding: the signature of x-sub extends this signature" + (define-unit-binding u 1 (import) (export x-sig x-sub))) +(test-syntax-error + "define-unit-binding: the signature of x-sub extends this signature" + (define-unit-binding u 1 (import) (export x-sub x-sig))) +(test-syntax-error + "define-unit-binding: initialization dependency on unknown import" + (define-unit-binding u 1 (import x-sig) (export) (init-depend x-sub))) +(test-syntax-error + "define-unit-binding: initialization dependency on unknown import" + (define-unit-binding u 1 (import x-sub) (export) (init-depend x-sig))) -(test-syntax-error "define-unit: missing name, import, export" - (define-unit)) -(test-syntax-error "define-unit: missing import, export" - (define-unit a)) +(test-syntax-error + "define-unit: missing unit name, import clause, and export clause" + (define-unit)) +(test-syntax-error + "define-unit: missing import and export clauses" + (define-unit a)) (test-syntax-error "define-unit: missing export" - (define-unit a (import))) -(test-syntax-error "define-unit: missing name" - (define-unit (import) (export))) -(test-syntax-error "define-unit: bad name" - (define-unit "x" (import) (export))) -(test-syntax-error "define-unit: bad syntax" - (define-unit x (unit (import) (export)))) -(test-runtime-error exn:fail:contract? "define-unit: bad set!" - (let () - (define-signature s ()) - (define-unit x (import) (export) 1) - (set! x (unit (import s) (export) 1)))) -(test-runtime-error exn:fail:contract? "define-unit: bad set!" - (let () - (define-signature s ()) - (define-unit x (import) (export s) 1) - (set! x (unit (import) (export) 1)))) + (define-unit a (import))) +(test-syntax-error + "define-unit: not an identifier" + (define-unit (import) (export))) +(test-syntax-error + "define-unit: not an identifier" + (define-unit "x" (import) (export))) +(test-syntax-error + "define-unit: import clause must start with keyword \"import\"" + (define-unit x (unit (import) (export)))) +(test-runtime-error exn:fail:contract? "set!: unit argument expects an untagged import with signature s, which this usage context does not supply" + (let () + (define-signature s ()) + (define-unit x (import) (export) 1) + (set! x (unit (import s) (export) 1)))) +(test-runtime-error exn:fail:contract? "set!: this usage context expects a unit with an untagged export with signature s, which the given unit does not supply" + (let () + (define-signature s ()) + (define-unit x (import) (export s) 1) + (set! x (unit (import) (export) 1)))) (test-syntax-error "define-compound-unit: missing import" - (define-compound-unit x)) -(test-syntax-error "define-compound-unit: missing name" - (define-compound-unit)) -(test-syntax-error "define-compound-unit: missing name" - (define-compound-unit (import) (link) (export))) -(test-syntax-error "define-compound-unit: bad name" - (define-compound-unit 1 (import) (link) (export))) + (define-compound-unit x)) +(test-syntax-error + "define-compound-unit: missing unit name" + (define-compound-unit)) +(test-syntax-error + "define-compound-unit: not an identifier" + (define-compound-unit (import) (link) (export))) +(test-syntax-error + "define-compound-unit: not an identifier" + (define-compound-unit 1 (import) (link) (export))) -(test-syntax-error "invoke-unit/infer : no unit" - (invoke-unit/infer)) -(test-syntax-error "invoke-unit/infer : not a unit" - (invoke-unit/infer 1)) -(test-syntax-error "invoke-unit/infer : not a unit" - (let ([x 1]) (invoke-unit/infer x))) -(test-syntax-error "invoke-unit/infer : not a unit" - (let-syntax ([x 1]) (invoke-unit/infer x))) -(test-syntax-error "invoke-unit/infer: too much" - (invoke-unit/infer x y)) +(test-syntax-error + "invoke-unit/infer: missing unit" + (invoke-unit/infer)) +(test-syntax-error + "invoke-unit/infer: not an identifier" + (invoke-unit/infer 1)) +(test-syntax-error + "invoke-unit/infer: unknown unit definition" + (let ([x 1]) (invoke-unit/infer x))) +(test-syntax-error + "invoke-unit/infer: not a unit definition" + (let-syntax ([x 1]) (invoke-unit/infer x))) +(test-syntax-error + "invoke-unit/infer: expected syntax matching (invoke-unit/infer ) or (invoke-unit/infer (link ...))" + (invoke-unit/infer x y)) (define-unit u (import x-sig) (export)) (define-unit v (import) (export x-sig) (define x 3)) -(test-syntax-error "invoke-unit/infer : no unit" - (invoke-unit/infer (link))) -(test-syntax-error "invoke-unit/infer : not a unit" - (invoke-unit/infer (link 1 u))) -(test-syntax-error "invoke-unit/infer : not a unit" - (let ([x 1]) (invoke-unit/infer (link u x)))) -(test-syntax-error "invoke-unit/infer : not a unit" - (let-syntax ([x 1]) (invoke-unit/infer (link x u)))) +(test-syntax-error + "invoke-unit/infer: no units in link clause" + (invoke-unit/infer (link))) +(test-syntax-error + "invoke-unit/infer: not an identifier" + (invoke-unit/infer (link 1 u))) +(test-syntax-error + "invoke-unit/infer: unknown unit definition" + (let ([x 1]) (invoke-unit/infer (link u x)))) +(test-syntax-error + "invoke-unit/infer: not a unit definition" + (let-syntax ([x 1]) (invoke-unit/infer (link x u)))) (invoke-unit/infer (link u v)) -(test-syntax-error "define-values/invoke-unit/infer: no unit" - (define-values/invoke-unit/infer)) +(test-syntax-error + "define-values/invoke-unit/infer: missing unit" + (define-values/invoke-unit/infer)) +(test-syntax-error + "define-values/invoke-unit/infer: not an identifier" + (define-values/invoke-unit/infer 1)) +(test-syntax-error + "define-values/invoke-unit/infer: unknown unit definition" + (let ((x 1)) + (define-values/invoke-unit/infer x))) (test-syntax-error "define-values/invoke-unit/infer: not a unit" - (define-values/invoke-unit/infer 1)) -(test-syntax-error "define-values/invoke-unit/infer: not a unit" - (let ((x 1)) - (define-values/invoke-unit/infer x))) -(test-syntax-error "define-values/invoke-unit/infer: not a unit" - (let-syntax ((x 1)) - (define-values/invoke-unit/infer x))) -(test-syntax-error "define-values/invoke-unit/infer: too much" - (define-values/invoke-unit/infer x y)) + (let-syntax ((x 1)) + (define-values/invoke-unit/infer x))) +(test-syntax-error + "define-values/invoke-unit/infer: expected syntax matching (define-values/invoke-unit/infer [(export )] ) or (define-values/invoke-unit/infer [(export )] (link ...))" + (define-values/invoke-unit/infer x y)) (define-unit u (import x-sig) (export) x) (define-unit v (import) (export x-sig) (define x 3)) (test-syntax-error "define-values/invoke-unit/infer: no unit" - (define-values/invoke-unit/infer (link))) + (define-values/invoke-unit/infer (link))) +(test-syntax-error + "define-values/invoke-unit/infer: not an identifier" + (define-values/invoke-unit/infer (link 1 u))) +(test-syntax-error + "define-values/invoke-unit/infer: unknown unit definition" + (let ([x 1]) + (define-values/invoke-unit/infer (link u x)))) (test-syntax-error "define-values/invoke-unit/infer: not a unit" - (define-values/invoke-unit/infer (link 1 u))) -(test-syntax-error "define-values/invoke-unit/infer: not a unit" - (let ([x 1]) - (define-values/invoke-unit/infer (link u x)))) -(test-syntax-error "define-values/invoke-unit/infer: not a unit" - (let-syntax ([x 1]) - (define-values/invoke-unit/infer (link u x)))) + (let-syntax ([x 1]) + (define-values/invoke-unit/infer (link u x)))) (test-runtime-error - exn:fail:contract:variable? - "undefined" + exn:fail:contract:variable? "undefined" (let () (define-values/invoke-unit/infer (link u v)) x)) (test-runtime-error - exn:fail:contract:variable? - "undefined" + exn:fail:contract:variable? "undefined" (let () (define-values/invoke-unit/infer (export x-sig) (link u v)) x)) @@ -1396,19 +1582,22 @@ (let () (define-values/invoke-unit/infer (export x-sig) v) x) -(test-syntax-error "define-values/invoke-unit/infer: doesn't export y" - (define-values/invoke-unit/infer (export y-sig) (link u v))) +(test-syntax-error + "define-values/invoke-unit/infer: no subunit exports signature y-sig" + (define-values/invoke-unit/infer (export y-sig) (link u v))) -(test-runtime-error exn? "define-values/invoke-unit/infer: unbound variable: x" - (let () - (define-values/invoke-unit/infer (export) (link u v)) - x)) -(test-syntax-error "define-values/invoke-unit/infer: doesn't export y" - (define-values/invoke-unit/infer (export y-sig) v)) -(test-runtime-error exn? "define-values/invoke-unit/infer: unbound variable: x" - (let () - (define-values/invoke-unit/infer (export) v) - x)) +(test-runtime-error exn? "x: undefined" + (let () + (define-values/invoke-unit/infer (export) (link u v)) + x)) +(test-syntax-error + "define-values/invoke-unit/infer: no subunit exports signature y-sig" + (define-values/invoke-unit/infer (export y-sig) v)) +(test-runtime-error exn? + "x: undefined" + (let () + (define-values/invoke-unit/infer (export) v) + x)) (let () (define-signature s^ (a)) @@ -1423,37 +1612,64 @@ (export s^) (define a 2)) (define-values/invoke-unit/infer (export) (link v@ u@)) - (test-syntax-error "define-values/invoke-unit/infer: init-depend broken" - (define-values/invoke-unit/infer (export) (link u@ v@)))) + (void)) -(define-unit u (import x-sig) (export) x) -(test-syntax-error "define-values/invoke-unit/infer: bad imports" - (define-values/invoke-unit/infer u)) -(define-unit u (import x-sig y-sig) (export)) -(test-syntax-error "define-values/invoke-unit/infer: bad imports" - (define-values/invoke-unit/infer u)) +(test-syntax-error + + "define-values/invoke-unit/infer: unit depends on initialization of later unit" + (let () + (define-signature s^ (a)) + (define-signature t^ (b)) + (define-unit u@ + (import s^) + (export t^) + (init-depend s^) + (define b a)) + (define-unit v@ + (import) + (export s^) + (define a 2)) + (define-values/invoke-unit/infer (export) (link u@ v@)) + (void))) + +(test-syntax-error + + "x: unbound identifier in module" + (module foo racket + (define-signature x-sig (x)) + (define-unit u (import x-sig) (export) x) + (define-values/invoke-unit/infer u))) + +(test-syntax-error + + "y: unbound identifier in module" + (module foo racket + (define-signature x-sig (x)) + (define-signature y-sig (y)) + (define-unit u (import x-sig y-sig) (export)) + (define-values/invoke-unit/infer u))) (define-unit u (import) (export x-sig y-sig) (define x 10) (define y 20)) (test 30 - (let () - (define-values/invoke-unit/infer u) - (+ y x))) + (let () + (define-values/invoke-unit/infer u) + (+ y x))) (test 1 - (let () - (define-unit x (import) (export) 1) - (invoke-unit x))) + (let () + (define-unit x (import) (export) 1) + (invoke-unit x))) (test 1 - (let () - (define-unit x (import) (export) 1) - (let ((u 1)) - (invoke-unit x)))) + (let () + (define-unit x (import) (export) 1) + (let ((u 1)) + (invoke-unit x)))) (test 2 - (let () - (define-unit x (import) (export) 1) - (set! x (unit (import) (export) 2)) - (invoke-unit x))) + (let () + (define-unit x (import) (export) 1) + (set! x (unit (import) (export) 2)) + (invoke-unit x))) @@ -1472,19 +1688,24 @@ (test-syntax-error "compound-unit/infer: missing export" - (compound-unit/infer (link) (import))) -(test-syntax-error "compound-unit/infer: bad unit" - (compound-unit/infer (import) (export) (link 1))) -(test-syntax-error "compound-unit/infer: bad import" - (compound-unit/infer (import (a : b)) (export) (link))) -(test-syntax-error "compound-unit/infer: bad link" - (compound-unit/infer (import) (export) (link (((A : b)) c)))) + (compound-unit/infer (link) (import))) +(test-syntax-error + "compound-unit/infer: bad linking line" + (compound-unit/infer (import) (export) (link 1))) +(test-syntax-error + "compound-unit/infer: unknown signature" + (compound-unit/infer (import (a : fake-signature)) (export) (link))) +(test-syntax-error + "compound-unit/infer: unknown unit definition" + (compound-unit/infer (import) (export) (link (((A : b)) c)))) +(test-syntax-error +"compound-unit/infer: unknown signature" + (compound-unit/infer (import ??) (export) (link))) (test-syntax-error "compound-unit/infer: unknown sig" - (compound-unit/infer (import ??) (export) (link))) -(test-syntax-error "compound-unit/infer: unknown sig" - (compound-unit/infer (import) (export ??) (link))) -(test-syntax-error "compound-unit/infer: unknown sig" - (compound-unit/infer (import) (export) (link (() u ??)))) + (compound-unit/infer (import) (export ??) (link))) +(test-syntax-error + "compound-unit/infer: unknown linking identifier" + (compound-unit/infer (import) (export) (link (() u ??)))) (define-unit x @@ -1516,14 +1737,44 @@ (export) (+ x y z)) -(test-syntax-error "compound-unit/infer: re-export" - (compound-unit/infer (import (l : x-sig)) (export x-sig) (link))) -(test-syntax-error "compound-unit/infer: duplicate def and import" - (compound-unit/infer (import y-sig x-sig) (export) (link x y))) -(test-syntax-error "compound-unit/infer: unprovided sig" - (compound-unit/infer (import) (export) (link x))) -(test-syntax-error "compound-unit/infer: unprovided sig" - (compound-unit/infer (import) (export x-sig) (link))) +(test-syntax-error + + "compound-unit/infer: cannot directly export an import" + (module foo racket + (define-signature x-sig (x)) + (compound-unit/infer (import (l : x-sig)) (export x-sig) (link)))) +(test-syntax-error + + "compound-unit/infer: multiple linkages satisfy untagged x-sig import" + (module foo racket + (define-signature x-sig (x)) + (define-signature y-sig (y)) + (define-unit x + (import x-sig) + (export y-sig) + (define y x) + y) + (define-unit y + (import y-sig) + (export (rename x-sig (x x))) + (define x y) + x) + (compound-unit/infer (import y-sig x-sig) (export) (link x y)))) +(test-syntax-error + "compound-unit/infer: no linkages satisfy untagged x-sig import" + (module foo racket + (define-signature x-sig (x)) + (define-signature y-sig (y)) + (define-unit x + (import x-sig) + (export y-sig) + (define y x) + y) + (compound-unit/infer (import) (export) (link x)))) +(test-syntax-error + + "compound-unit/infer: no sub unit exports this signature" + (compound-unit/infer (import) (export x-sig) (link))) (test-runtime-error exn:fail:contract:variable? @@ -1533,16 +1784,16 @@ (link x y)))) (test 3 - (let () - (define-signature s (x y)) - (let ((x 1) - (y 2)) - (define-unit-from-context u1 s) - (define-unit u2 (import (prefix : s)) (export) - (+ :x :y)) - (invoke-unit - (compound-unit/infer (import) (export) - (link u1 u2)))))) + (let () + (define-signature s (x y)) + (let ((x 1) + (y 2)) + (define-unit-from-context u1 s) + (define-unit u2 (import (prefix : s)) (export) + (+ :x :y)) + (invoke-unit + (compound-unit/infer (import) (export) + (link u1 u2)))))) (test 6 (invoke-unit (compound-unit/infer (import) (export) @@ -1589,335 +1840,348 @@ (test 12 x)) -(let () - (define-unit u (import) (export x-sig) - (define x 12)) - (define-unit u2 (import) (export x-sig) - (define x 13)) - (define-unit v (import) (export y-sig) - (define y 11)) - (define-unit v2 (import) (export y-sig) - (define y 1)) - (define-unit u3 (import y-sig x-sig) (export) - (+ y x)) - (test 24 + (let () + (define-unit u (import) (export x-sig) + (define x 12)) + (define-unit u2 (import) (export x-sig) + (define x 13)) + (define-unit v (import) (export y-sig) + (define y 11)) + (define-unit v2 (import) (export y-sig) + (define y 1)) + (define-unit u3 (import y-sig x-sig) (export) + (+ y x)) + (test 24 + (invoke-unit + (compound-unit/infer (import) (export) + (link (((l : x-sig)) u) + (((l2 : x-sig)) u2) + (((l3 : y-sig)) v) + (((l4 : y-sig)) v2) + (() u3 l2 l3)))))) + + ;; unit/new-import-export + + (test-runtime-error exn:fail:contract? "unit/new-import-export: result of unit expression was not a unit: 1" + (unit/new-import-export (import) (export) + (() 1))) + + (test-runtime-error exn:fail:contract? "unit/new-import-export: this usage context expects a unit with an untagged export with signature x-sig, which the given unit does not supply" + (unit/new-import-export (import) (export) + ((x-sig) (unit (import) (export))))) + + + (test-runtime-error exn:fail:contract? "unit/new-import-export: unit argument expects an untagged import with signature x-sig, which this usage context does not supply" + (unit/new-import-export (import) (export) + (() (unit (import x-sig) (export))))) + + (define-unit u (import x-sig) (export y-sig) + (define y x)) + + (test-syntax-error + + "unit/new-import-export: identifier x is not present in new imports" + (module foo racket + (define-signature x-sig (x)) + (define-signature y-sig (y)) + (define-unit u (import x-sig) (export y-sig) + (define y x)) + (unit/new-import-export (import) (export x-sig) + ((y-sig) u x-sig)))) + + (test-syntax-error + + "unit/new-import-export: identifier z is not present in old exports" + (module foo racket + (define-signature x-sig (x)) + (define-signature y-sig (y)) + (define-signature z-sig (z)) + (define-unit u (import x-sig) (export y-sig) + (define y x)) + (unit/new-import-export (import x-sig) (export y-sig z-sig) + ((y-sig) u x-sig)))) + + (let () + (define-unit u + (import xy-sig) (export z-sig) + (define z (+ x y))) + (define-unit v + (import) (export x-sig y-sig) + (define x 4) + (define y 8)) + (define-unit w (import z-sig) (export) + z) + (define-unit/new-import-export u2 (import x-sig y-sig) (export z-sig) + ((z-sig) u xy-sig)) + (test 12 + (invoke-unit (compound-unit/infer (import) (export) + (link v u2 w))))) + + (let () + (define-unit u + (import x-sig y-sig) (export z-sig) + (define z (+ x y))) + (define-unit v + (import) (export xy-sig) + (define x 4) + (define y 8)) + (define-unit w (import z-sig) (export) + z) + (define-unit/new-import-export u2 (import xy-sig) (export z-sig) + ((z-sig) u y-sig x-sig)) + (test 12 + (invoke-unit (compound-unit/infer (import) (export) + (link v u2 w))))) + + (let () + (define-unit u + (import xy-sig) (export z-sig) + (define z (+ x y))) + (define-unit v + (import) (export x-sig y-sig) + (define x 4) + (define y 8)) + (define-unit w (import z-sig) (export) + z) + (define-unit/new-import-export v2 (import) (export xy-sig) + ((x-sig y-sig) v)) + (test 12 + (invoke-unit (compound-unit/infer (import) (export) + (link v2 u w))))) + + (let () + (define-unit u + (import x-sig y-sig) (export z-sig) + (define z (+ x y))) + (define-unit v + (import) (export xy-sig) + (define x 4) + (define y 8)) + (define-unit w (import z-sig) (export) + z) + (define-unit/new-import-export v2 (import) (export y-sig x-sig) + ((xy-sig) v)) + (test 12 + (invoke-unit (compound-unit/infer (import) (export) + (link v2 u w))))) + + + + + ;; open + (let () + (define-signature xzy + ((open x-sig) (open y-sig) (open z-sig))) + + (define-unit u (import xzy) (export) + (+ x z y)) + + (define-unit v (import) (export xzy) + (define x 10) + (define y 20) + (define z 30)) + + (test 60 + (invoke-unit (compound-unit/infer (import) (export) (link v u))))) + + (let ([x 1] + [y 2] + [z 3]) + (define-signature xzy + ((open x-sig) (open y-sig) (open z-sig))) + + (define-unit u (import xzy) (export) + (+ x z y)) + + (define-unit v (import) (export xzy) + (define x 10) + (define y 20) + (define z 30)) + + (test 60 + (invoke-unit (compound-unit/infer (import) (export) (link v u))))) + + (define-signature s + (x (define-values (y) (add1 x)))) + + (let ([x 1] + [y 10] + [s:x 100] + [s:y 1000]) + (define-signature s2 + ((open (prefix s: s)) x (define-values (y) (sub1 x)))) + (define-unit u1 (import s2) (export) + (list s:x s:y x y)) + (define-unit u2 (import) (export s2) + (define s:x 3) + (define x 19)) + (test '(3 4 19 18) + (invoke-unit (compound-unit/infer (import) (export) (link u2 u1))))) + + + (define-signature sig^ (u-a)) + + (define-unit unit@ + (import) + (export sig^) + + (define u-a 'zero)) + + (test 'zero + (let ([q:u-a 5]) + (define-values/invoke-unit unit@ (import) (export (prefix q: sig^))) + q:u-a)) + + (define-syntax (use-unit stx) + (syntax-case stx () + [(_) + #'(let () + (define-values/invoke-unit unit@ (import) (export sig^)) + u-a)])) + + (define-syntax (use-unit2 stx) + (syntax-case stx () + [(_) + #'(let () + (define-values/invoke-unit/infer unit@) + u-a)])) + + (define-syntax (use-unit-badly1 stx) + (syntax-case stx () + [(_ u-a) + #'(let () + (define-values/invoke-unit unit@ (import) (export sig^)) + u-a)])) + + (define-syntax (use-unit-badly2 stx) + (syntax-case stx () + [(_ sig^) + #'(let () + (define-values/invoke-unit unit@ (import) (export sig^)) + u-a)])) + + (test 'zero (use-unit)) + (test 'zero (use-unit2)) + (test-runtime-error exn:fail:contract:variable? "u-a: undefined;\n cannot reference undefined identifier" + (use-unit-badly1 u-a)) + (test-runtime-error exn:fail:contract:variable? "u-a: undefined;\n cannot reference undefined identifier" + (use-unit-badly2 sig^)) + + (test 12 + (let () + (define-signature s^ (x)) + (define-unit u@ + (import) + (export s^) + (define x 12)) + (define-values/invoke-unit u@ (import) (export s^)) + x)) + + ;; ---------------------------------------- + ;; May sure unit body expansion doesn't mangle context: + + (test 5 (invoke-unit - (compound-unit/infer (import) (export) - (link (((l : x-sig)) u) - (((l2 : x-sig)) u2) - (((l3 : y-sig)) v) - (((l4 : y-sig)) v2) - (() u3 l2 l3)))))) + (let ([x 5]) + (define-syntax-rule (m) x) + (unit (import) (export) + (define x 6) + (m))))) -;; unit/new-import-export - -(test-runtime-error exn:fail:contract? "unit/new-import-export: not a unit" - (unit/new-import-export (import) (export) - (() 1))) - -(test-runtime-error exn:fail:contract? "unit/new-import-export: not a subtype" - (unit/new-import-export (import) (export) - ((x-sig) (unit (import) (export))))) - - -(test-runtime-error exn:fail:contract? "unit/new-import-export: not a subtype" - (unit/new-import-export (import) (export) - (() (unit (import x-sig) (export))))) - -(define-unit u (import x-sig) (export y-sig) - (define y x)) - -(test-syntax-error "unit/new-import-export: not enough imports" - (unit/new-import-export (import) (export x-sig) - ((y-sig) u x-sig))) - -(test-syntax-error "unit/new-import-export: too many exports" - (unit/new-import-export (import x-sig) (export y-sig z-sig) - ((y-sig) u x-sig))) - -(let () - (define-unit u - (import xy-sig) (export z-sig) - (define z (+ x y))) - (define-unit v - (import) (export x-sig y-sig) - (define x 4) - (define y 8)) - (define-unit w (import z-sig) (export) - z) - (define-unit/new-import-export u2 (import x-sig y-sig) (export z-sig) - ((z-sig) u xy-sig)) - (test 12 - (invoke-unit (compound-unit/infer (import) (export) - (link v u2 w))))) - -(let () - (define-unit u - (import x-sig y-sig) (export z-sig) - (define z (+ x y))) - (define-unit v - (import) (export xy-sig) - (define x 4) - (define y 8)) - (define-unit w (import z-sig) (export) - z) - (define-unit/new-import-export u2 (import xy-sig) (export z-sig) - ((z-sig) u y-sig x-sig)) - (test 12 - (invoke-unit (compound-unit/infer (import) (export) - (link v u2 w))))) - -(let () - (define-unit u - (import xy-sig) (export z-sig) - (define z (+ x y))) - (define-unit v - (import) (export x-sig y-sig) - (define x 4) - (define y 8)) - (define-unit w (import z-sig) (export) - z) - (define-unit/new-import-export v2 (import) (export xy-sig) - ((x-sig y-sig) v)) - (test 12 - (invoke-unit (compound-unit/infer (import) (export) - (link v2 u w))))) - -(let () - (define-unit u - (import x-sig y-sig) (export z-sig) - (define z (+ x y))) - (define-unit v - (import) (export xy-sig) - (define x 4) - (define y 8)) - (define-unit w (import z-sig) (export) - z) - (define-unit/new-import-export v2 (import) (export y-sig x-sig) - ((xy-sig) v)) - (test 12 - (invoke-unit (compound-unit/infer (import) (export) - (link v2 u w))))) - - - - -;; open -(let () - (define-signature xzy - ((open x-sig) (open y-sig) (open z-sig))) - - (define-unit u (import xzy) (export) - (+ x z y)) - - (define-unit v (import) (export xzy) - (define x 10) - (define y 20) - (define z 30)) - - (test 60 - (invoke-unit (compound-unit/infer (import) (export) (link v u))))) - -(let ([x 1] - [y 2] - [z 3]) - (define-signature xzy - ((open x-sig) (open y-sig) (open z-sig))) - - (define-unit u (import xzy) (export) - (+ x z y)) - - (define-unit v (import) (export xzy) - (define x 10) - (define y 20) - (define z 30)) - - (test 60 - (invoke-unit (compound-unit/infer (import) (export) (link v u))))) - -(define-signature s - (x (define-values (y) (add1 x)))) - -(let ([x 1] - [y 10] - [s:x 100] - [s:y 1000]) - (define-signature s2 - ((open (prefix s: s)) x (define-values (y) (sub1 x)))) - (define-unit u1 (import s2) (export) - (list s:x s:y x y)) - (define-unit u2 (import) (export s2) - (define s:x 3) - (define x 19)) - (test '(3 4 19 18) - (invoke-unit (compound-unit/infer (import) (export) (link u2 u1))))) - - -(define-signature sig^ (u-a)) - -(define-unit unit@ - (import) - (export sig^) - - (define u-a 'zero)) - -(test 'zero - (let ([q:u-a 5]) - (define-values/invoke-unit unit@ (import) (export (prefix q: sig^))) - q:u-a)) - -(define-syntax (use-unit stx) - (syntax-case stx () - [(_) - #'(let () - (define-values/invoke-unit unit@ (import) (export sig^)) - u-a)])) - -(define-syntax (use-unit2 stx) - (syntax-case stx () - [(_) - #'(let () - (define-values/invoke-unit/infer unit@) - u-a)])) - -(define-syntax (use-unit-badly1 stx) - (syntax-case stx () - [(_ u-a) - #'(let () - (define-values/invoke-unit unit@ (import) (export sig^)) - u-a)])) - -(define-syntax (use-unit-badly2 stx) - (syntax-case stx () - [(_ sig^) - #'(let () - (define-values/invoke-unit unit@ (import) (export sig^)) - u-a)])) - -(test 'zero (use-unit)) -(test 'zero (use-unit2)) -(test-runtime-error exn:fail:contract:variable? "context mismatch; no u-a" - (use-unit-badly1 u-a)) -(test-runtime-error exn:fail:contract:variable? "context mismatch; no u-a" - (use-unit-badly2 sig^)) - -(test 12 - (let () - (define-signature s^ (x)) - (define-unit u@ - (import) - (export s^) - (define x 12)) - (define-values/invoke-unit u@ (import) (export s^)) - x)) - -;; ---------------------------------------- -;; May sure unit body expansion doesn't mangle context: - -(test 5 - (invoke-unit - (let ([x 5]) - (define-syntax-rule (m) x) - (unit (import) (export) - (define x 6) - (m))))) - -(test 5 - (invoke-unit - (let-syntax ([x (syntax-rules () - [(_) 5])]) - (define-syntax-rule (m) (x)) - (unit (import) (export) - (define (x) 6) - (m))))) - -;; ---------------------------------------- - -;; Make sure that right-hand side of a `define-values` -;; has the right scope, including in the case of -;; signature extension. -;; Based on examples from Dan Feltey. - -(parameterize ([current-namespace (make-base-namespace)]) - (eval - '(module scope-check/a-sig racket - (provide a^) - (define-signature a^ ((define-values (a) (+ b 1)))) - (define b 7))) - (eval - '(module scope-check/b-sig racket - (require 'scope-check/a-sig) - (provide result) - - (define-signature b^ extends a^ (b)) - - (define b-out@ (unit (import) (export b^) - (define b "BAD"))) - (define b-in@ - (unit (import b^) (export) a)) - (define result + (test 5 (invoke-unit - (compound-unit (import) (export) - (link (((B : b^)) b-out@) - (() b-in@ B))))))) - (test 8 (dynamic-require ''scope-check/b-sig 'result))) + (let-syntax ([x (syntax-rules () + [(_) 5])]) + (define-syntax-rule (m) (x)) + (unit (import) (export) + (define (x) 6) + (m))))) -(parameterize ([current-namespace (make-base-namespace)]) - (eval - '(module scope-check/a-sig racket - (provide a^) - (define-signature a^ ((define-values (a) (+ b 1)))) - (define b 7))) - (eval - '(module scope-check/b-sig racket - (require 'scope-check/a-sig) - (provide result) + ;; ---------------------------------------- - (define-signature b^ extends a^ ()) - (define b "BAD") + ;; Make sure that right-hand side of a `define-values` + ;; has the right scope, including in the case of + ;; signature extension. + ;; Based on examples from Dan Feltey. - (define b-out@ (unit (import) (export b^))) - (define b-in@ - (unit (import b^) (export) a)) - (define result - (invoke-unit - (compound-unit (import) (export) - (link (((B : b^)) b-out@) - (() b-in@ B))))))) - (test 8 (dynamic-require ''scope-check/b-sig 'result))) + (parameterize ([current-namespace (make-base-namespace)]) + (eval + '(module scope-check/a-sig racket + (provide a^) + (define-signature a^ ((define-values (a) (+ b 1)))) + (define b 7))) + (eval + '(module scope-check/b-sig racket + (require 'scope-check/a-sig) + (provide result) -;; ---------------------------------------- + (define-signature b^ extends a^ (b)) -(module check-define-values-invoke-unit-spec racket/base - (require racket/unit) + (define b-out@ (unit (import) (export b^) + (define b "BAD"))) + (define b-in@ + (unit (import b^) (export) a)) + (define result + (invoke-unit + (compound-unit (import) (export) + (link (((B : b^)) b-out@) + (() b-in@ B))))))) + (test 8 (dynamic-require ''scope-check/b-sig 'result))) - (define-signature a^ (foo)) - (define-signature b^ (bar)) + (parameterize ([current-namespace (make-base-namespace)]) + (eval + '(module scope-check/a-sig racket + (provide a^) + (define-signature a^ ((define-values (a) (+ b 1)))) + (define b 7))) + (eval + '(module scope-check/b-sig racket + (require 'scope-check/a-sig) + (provide result) - (define-unit works@ - (import) (export a^) (define foo 'foo)) - (define-values/invoke-unit/infer - (export (rename a^ [qux foo])) - works@) + (define-signature b^ extends a^ ()) + (define b "BAD") - (define-unit doesnt@ - (import) (export b^) (define bar 0)) - (define-unit work@ - (import b^) (export a^) (define foo bar)) - ;; No rename on export - (define-values/invoke-unit/infer - (export a^) - (link doesnt@ work@)) - ;; Rename on export - (define-values/invoke-unit/infer - (export (rename a^ [baz foo])) - (link doesnt@ work@)) + (define b-out@ (unit (import) (export b^))) + (define b-in@ + (unit (import b^) (export) a)) + (define result + (invoke-unit + (compound-unit (import) (export) + (link (((B : b^)) b-out@) + (() b-in@ B))))))) + (test 8 (dynamic-require ''scope-check/b-sig 'result))) - (provide results) - (define results (list foo baz))) + ;; ---------------------------------------- -(test '(0 0) (dynamic-require ''check-define-values-invoke-unit-spec 'results)) + (module check-define-values-invoke-unit-spec racket/base + (require racket/unit) -;; ---------------------------------------- + (define-signature a^ (foo)) + (define-signature b^ (bar)) -(displayln "tests passed") + (define-unit works@ + (import) (export a^) (define foo 'foo)) + (define-values/invoke-unit/infer + (export (rename a^ [qux foo])) + works@) + + (define-unit doesnt@ + (import) (export b^) (define bar 0)) + (define-unit work@ + (import b^) (export a^) (define foo bar)) + ;; No rename on export + (define-values/invoke-unit/infer + (export a^) + (link doesnt@ work@)) + ;; Rename on export + (define-values/invoke-unit/infer + (export (rename a^ [baz foo])) + (link doesnt@ work@)) + + (provide results) + (define results (list foo baz))) + + (test '(0 0) (dynamic-require ''check-define-values-invoke-unit-spec 'results)) + + ;; ---------------------------------------- diff --git a/racket/collects/racket/private/unit-contract-syntax.rkt b/racket/collects/racket/private/unit-contract-syntax.rkt index ceb24ad9e9..e4dcd8b2d9 100644 --- a/racket/collects/racket/private/unit-contract-syntax.rkt +++ b/racket/collects/racket/private/unit-contract-syntax.rkt @@ -3,22 +3,16 @@ (require syntax/parse "unit-compiletime.rkt" "unit-keywords.rkt" - (for-template "unit-keywords.rkt")) + racket/contract + (for-template "unit-keywords.rkt" racket/base racket/contract)) -(provide import-clause/contract export-clause/contract dep-clause - import-clause/c export-clause/c) - -(define-syntax-class sig-id - #:attributes () - (pattern x - #:declare x (static (λ (x) - (signature? (set!-trans-extract x))) - 'signature))) +(provide import-clause/contract export-clause/contract body-clause/contract dep-clause + import-clause/c export-clause/c body-clause/c) (define-syntax-class sig-spec #:literals (prefix rename only except) #:attributes ((name 0)) #:transparent - (pattern name:sig-id) + (pattern name:identifier) (pattern (prefix i:identifier s:sig-spec) #:with name #'s.name) (pattern (rename s:sig-spec [int:identifier ext:identifier] ...) @@ -38,8 +32,8 @@ (define-syntax-class tagged-sig-id #:literals (tag) #:attributes () #:transparent - (pattern s:sig-id) - (pattern (tag i:identifier s:sig-id))) + (pattern s:identifier) + (pattern (tag i:identifier s))) (define-syntax-class unit/c-clause #:auto-nested-attributes @@ -57,6 +51,62 @@ #:transparent (pattern (export e:unit/c-clause ...))) +;; Helper to reduce the size of unit contract expansion +;; This has to be defined in a module in order for +;; `unit/c-check-invoke-values` to be defined at the +;; correct phase during expansion when the body-clause/c +;; syntax class is parsed +(module unit-check-values racket/base + (provide unit/c-check-invoke-values) + (require racket/contract/base + racket/contract/combinator) + (define ((unit/c-check-invoke-values len blame ctcs) . args) + (define args-len (length args)) + (unless (= len args-len) + (raise-blame-error (blame-add-context blame "the body of") + (blame-value blame) + (format "expected ~a values, returned ~a" len args-len))) + (apply values + (map + (lambda (ctc arg) (ctc arg)) + ctcs args)))) + +(require (for-template 'unit-check-values)) +(define-splicing-syntax-class body-clause/c + #:literals (values) + #:auto-nested-attributes + #:transparent + (pattern (~seq) + #:attr name #'() + #:attr make-define-ctcs/blame + (lambda (name blame) #'()) + #:attr apply-invoke-ctcs + (lambda (id blame ctcs) id)) + (pattern (values ctc:expr ...) + #:attr name #'('(values ctc ...)) + #:attr make-define-ctcs/blame + (lambda (name blame) + #`((define #,name + (map (lambda (c) ((contract-projection c) + (blame-add-context #,blame "the body of"))) + (list ctc ...))))) + #:attr apply-invoke-ctcs + ;; blame here is really syntax representing a blame object + (lambda (id blame ctcs) + (define len (length (syntax->list #'(ctc ...)))) + #`(call-with-values + (lambda () #,id) + (unit/c-check-invoke-values #,len #,blame #,ctcs)))) + (pattern b:expr + #:attr name #'('b) + #:attr make-define-ctcs/blame + (lambda (name blame) + #`((define #,name ((contract-projection b) + (blame-add-context #,blame "the body of"))))) + #:attr apply-invoke-ctcs + (lambda (id blame ctcs) + #`(#,ctcs #,id)))) + (define-syntax-class unit/contract-clause #:auto-nested-attributes #:transparent @@ -76,3 +126,7 @@ #:auto-nested-attributes #:transparent (pattern (init-depend s:tagged-sig-id ...))) +(define-splicing-syntax-class body-clause/contract + #:auto-nested-attributes + #:transparent + (pattern (~seq #:invoke/contract b:expr))) diff --git a/racket/collects/racket/private/unit-contract.rkt b/racket/collects/racket/private/unit-contract.rkt index 067f17462d..1c69a5bda4 100644 --- a/racket/collects/racket/private/unit-contract.rkt +++ b/racket/collects/racket/private/unit-contract.rkt @@ -4,6 +4,7 @@ syntax/boundmap syntax/name syntax/parse + (only-in racket/syntax generate-temporary) "unit-compiletime.rkt" "unit-contract-syntax.rkt" "unit-syntax.rkt") @@ -68,10 +69,18 @@ (define-for-syntax contract-imports (contract-imports/exports #t)) (define-for-syntax contract-exports (contract-imports/exports #f)) +;; This is copied from the unit implementation, but can't be required +;; from there since unit.rkt also requires this file +(define-for-syntax (tagged-sigid->tagged-siginfo x) + (cons (car x) + (signature-siginfo (lookup-signature (cdr x))))) (define-for-syntax (unit/c/core name stx) (syntax-parse stx - [(:import-clause/c :export-clause/c) + [(:import-clause/c + :export-clause/c + (~optional d:dep-clause #:defaults ([(d.s 1) null])) + b:body-clause/c) (begin (define-values (isig tagged-import-sigs import-tagged-infos import-tagged-sigids import-sigs) @@ -80,7 +89,15 @@ (define-values (esig tagged-export-sigs export-tagged-infos export-tagged-sigids export-sigs) (process-unit-export #'(e.s ...))) - + + (define deps (syntax->list #'(d.s ...))) + (define dep-tagged-siginfos + (map tagged-sigid->tagged-siginfo + (map check-tagged-id deps))) + + (define apply-body-contract (attribute b.apply-invoke-ctcs)) + (define make-define-ctcs/blame (attribute b.make-define-ctcs/blame)) + (define contract-table (make-bound-identifier-mapping)) @@ -102,12 +119,9 @@ [c (in-list (syntax->list cs))]) (bound-identifier-mapping-put! contract-table x c))) - (check-duplicate-sigs import-tagged-infos isig null null) - + (check-duplicate-sigs import-tagged-infos isig dep-tagged-siginfos deps) (check-duplicate-subs export-tagged-infos esig) - (check-unit-ie-sigs import-sigs export-sigs) - (for-each process-sig isig import-sigs @@ -119,7 +133,13 @@ (syntax->list #'((e.x ...) ...)) (syntax->list #'((e.c ...) ...))) - (with-syntax ([(isig ...) isig] + (with-syntax ([((dept . depr) ...) + (map + (lambda (tinfo) + (cons (car tinfo) + (syntax-local-introduce (car (siginfo-rtime-ids (cdr tinfo)))))) + dep-tagged-siginfos)] + [(isig ...) isig] [(esig ...) esig] [((import-key ...) ...) (map tagged-info->keys import-tagged-infos)] @@ -130,7 +150,8 @@ import-tagged-infos)] [(export-name ...) (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) - export-tagged-infos)]) + export-tagged-infos)] + [ctcs/blame (generate-temporary 'ctcs/blame)]) (quasisyntax/loc stx (begin (make-contract @@ -145,9 +166,13 @@ (list (cons 'esig (map list (list 'e.x ...) (build-compound-type-name 'e.c ...))) - ...))) + ...)) + (cons 'init-depend + (list 'd.s ...)) + #,@(attribute b.name)) #:projection (λ (blame) + #,@(make-define-ctcs/blame #'ctcs/blame #'blame) (λ (unit-tmp) (unit/c-first-order-check unit-tmp @@ -157,6 +182,7 @@ (vector-immutable (cons 'export-name (vector-immutable export-key ...)) ...) + (list (cons 'dept depr) ...) blame) (make-unit '#,name @@ -164,16 +190,19 @@ (vector-immutable import-key ...)) ...) (vector-immutable (cons 'export-name (vector-immutable export-key ...)) ...) - (unit-deps unit-tmp) + (list (cons 'dept depr) ...) (λ () (let-values ([(unit-fn export-table) ((unit-go unit-tmp))]) (values (lambda (import-table) - (unit-fn #,(contract-imports - #'import-table - import-tagged-infos - import-sigs - contract-table - #'blame))) + #,(apply-body-contract + #`(unit-fn #,(contract-imports + #'import-table + import-tagged-infos + import-sigs + contract-table + #'blame)) + #'blame + #'ctcs/blame)) #,(contract-exports #'export-table export-tagged-infos @@ -190,6 +219,7 @@ (vector-immutable (cons 'export-name (vector-immutable export-key ...)) ...) + (list (cons 'dept depr) ...) #f)))))))])) (define-syntax/err-param (unit/c stx) @@ -198,7 +228,7 @@ (let ([name (syntax-local-infer-name stx)]) (unit/c/core name #'sstx))])) -(define (unit/c-first-order-check val expected-imports expected-exports blame) +(define (unit/c-first-order-check val expected-imports expected-exports expected-deps blame) (let/ec return (define (failed str . args) (if blame @@ -224,12 +254,57 @@ [r (hash-ref t v0 #f)]) (when (not r) (let ([sub-name (car (vector-ref super-sig i))]) - (if import? - (failed "contract does not list import ~a" sub-name) - (failed "unit must export signature ~a" sub-name))))) + (define tag-part (vector-ref (cdr (vector-ref super-sig i)) 0)) + (define tag (and (pair? tag-part) (car tag-part))) + (failed + (string-append + (if import? + (format "contract does not list import ~a" sub-name) + (format "unit must export signature ~a" sub-name)) + (if tag + (format " with tag ~a" tag) + "")))))) (loop (sub1 i))))) + ;; check that the dependencies of the given unit are consistent with the + ;; dependencies specified by the contract. Ensures that the given dependencies + ;; are a subset of the expected dependencies otherwise raises a contract error. + (define (check-dependencies expected given imports) + (define (lookup dep lst) + (member dep lst (lambda (p1 p2) + (and (eq? (car p1) (car p2)) + (eq? (cdr p1) (cdr p2)))))) + ;; Normalize dependencies to be symbols or pairs of tags and symbols + (define (normalize-deps deps) + (map (lambda (dep) (if (car dep) dep (cdr dep))) deps)) + (define t (for*/hash ([i (in-vector imports)] + [v (in-value (cdr i))] + [im (in-value (vector-ref v 0))] + #:when (member im (normalize-deps expected)) + [vj (in-vector v)]) + (values vj #t))) + ;; use the imports to get the name and tag of dependency + (define (get-name dep-tag) + (define tag-table + (for/hash ([e (in-vector imports)]) + (define name (car e)) + (define v (vector-ref (cdr e) 0)) + (define tag (if (pair? v) (cdr v) v)) + (values tag name))) + (hash-ref tag-table dep-tag #f)) + (for ([dep (in-list (normalize-deps given))]) + (unless (hash-ref t dep #f) + (define tag (and (pair? dep) (car dep))) + (define sig-tag (or (and (pair? dep) (cdr dep)) dep)) + (failed + (string-append + (format "contract does not list initialization dependency ~a" + (get-name sig-tag)) + (if tag + (format " with tag ~a" tag) + "")))))) (unless (unit? val) (failed "not a unit")) (check-sig-subset expected-imports (unit-import-sigs val) #t) (check-sig-subset (unit-export-sigs val) expected-exports #f) + (check-dependencies expected-deps (unit-deps val) expected-imports) #t)) diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index 0704489c9f..c9e609c386 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -1933,14 +1933,18 @@ (build-unit-from-context sig)) "missing unit name and signature")) +;; A marker used when the result of invoking a unit should not be contracted +(define-for-syntax no-invoke-contract (gensym)) (define-for-syntax (build-unit/contract stx) (syntax-parse stx - [(:import-clause/contract :export-clause/contract dep:dep-clause . body) + [(:import-clause/contract :export-clause/contract dep:dep-clause :body-clause/contract . bexps) + (define splicing-body-contract + (if (eq? (syntax-e #'b) no-invoke-contract) #'() #'(b))) (let-values ([(exp isigs esigs deps) (build-unit (check-unit-syntax (syntax/loc stx - ((import i.s ...) (export e.s ...) dep . body))))]) + ((import i.s ...) (export e.s ...) dep . bexps))))]) (with-syntax ([name (syntax-local-infer-name (error-syntax))] [(import-tagged-sig-id ...) (map (λ (i s) @@ -1956,17 +1960,27 @@ [unit-contract (unit/c/core #'name - (syntax/loc stx + (quasisyntax/loc stx ((import (import-tagged-sig-id [i.x i.c] ...) ...) - (export (export-tagged-sig-id [e.x e.c] ...) ...))))]) + (export (export-tagged-sig-id [e.x e.c] ...) ...) + dep + #,@splicing-body-contract)))]) (values (syntax/loc stx (contract unit-contract new-unit '(unit name) (current-contract-region) (quote name) (quote-srcloc name))) isigs esigs deps))))] - [(ic:import-clause/contract ec:export-clause/contract . body) - (build-unit/contract - (syntax/loc stx - (ic ec (init-depend) . body)))])) + [(ic:import-clause/contract ec:export-clause/contract dep:dep-clause . bexps) + (build-unit/contract + (quasisyntax/loc stx + (ic ec dep #:invoke/contract #,no-invoke-contract . bexps)))] + [(ic:import-clause/contract ec:export-clause/contract bc:body-clause/contract . bexps) + (build-unit/contract + (quasisyntax/loc stx + (ic ec (init-depend) #,@(syntax->list #'bc) . bexps)))] + [(ic:import-clause/contract ec:export-clause/contract . bexps) + (build-unit/contract + (quasisyntax/loc stx + (ic ec (init-depend) #:invoke/contract #,no-invoke-contract . bexps)))])) (define-syntax/err-param (define-unit/contract stx) (build-define-unit/contracted stx (λ (stx) From 820ab7126cd1a857f3c3299125eb5d9f280f2de5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 11 Aug 2015 14:34:51 -0600 Subject: [PATCH 021/381] fix enum mismatch in ARM JIT Also, recognize `__ARM_ARCH_6ZK__`. --- racket/src/racket/src/lightning/arm/asm.h | 2 +- racket/src/racket/src/lightning/arm/fp-swf.h | 2 +- racket/src/racket/src/lightning/arm/fp-vfp.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/src/lightning/arm/asm.h b/racket/src/racket/src/lightning/arm/asm.h index 81e4b78212..7eaa50b327 100644 --- a/racket/src/racket/src/lightning/arm/asm.h +++ b/racket/src/racket/src/lightning/arm/asm.h @@ -124,7 +124,7 @@ typedef enum { # define JIT_ARM_THUMB 1 # define JIT_ARM_VERSION 5 # define JIT_ARM_EXTENDED 1 -#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6K__) +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) # define JIT_ARM_VERSION 6 #elif defined(__ARM_ARCH_6T__) || defined(__ARM_ARCH_6T2__) # define JIT_ARM_THUMB 2 diff --git a/racket/src/racket/src/lightning/arm/fp-swf.h b/racket/src/racket/src/lightning/arm/fp-swf.h index 8402493b99..c310f0ab46 100644 --- a/racket/src/racket/src/lightning/arm/fp-swf.h +++ b/racket/src/racket/src/lightning/arm/fp-swf.h @@ -570,7 +570,7 @@ swf_iff(jit_state_t _jitp, int (*i0)(float, float), __jit_inline void swf_idd(jit_state_t _jitp, int (*i0)(double, double), - jit_fpr_t r0, jit_fpr_t r1, jit_fpr_t r2) + jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { int l; l = 0xf; diff --git a/racket/src/racket/src/lightning/arm/fp-vfp.h b/racket/src/racket/src/lightning/arm/fp-vfp.h index d114395fd5..737b13315f 100644 --- a/racket/src/racket/src/lightning/arm/fp-vfp.h +++ b/racket/src/racket/src/lightning/arm/fp-vfp.h @@ -420,7 +420,7 @@ _vcmp_10_f(jit_state_t _jitp, int cc, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) } __jit_inline void -_vcmp_10_d(jit_state_t _jitp, int cc, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) +_vcmp_10_d(jit_state_t _jitp, int cc, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { _VCMP_F64(r1, r2); _vcmp10_x(_jitp, cc, r0); From 13bd0135282e5814197845e99fc6e159dc007c10 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 11 Aug 2015 15:29:58 -0600 Subject: [PATCH 022/381] fix JIT-inlined `set-cpointer-tag!` for non-x86 --- racket/src/racket/src/jitcommon.c | 2 +- racket/src/racket/src/jitinline.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 30cec6dc42..665ff8b904 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -3361,7 +3361,7 @@ static int common13(mz_jit_state *jitter, void *_data) scheme_jit_register_sub_func(jitter, sjc.slow_cpointer_tag_code, scheme_false); CHECK_LIMIT(); - /* *** slow_cpointer_tag_code *** */ + /* *** slow_set_cpointer_tag_code *** */ sjc.slow_set_cpointer_tag_code = jit_get_ip(); mz_prolog(JIT_R2); JIT_UPDATE_THREAD_RSPTR(); diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 22a667d228..a43e1cb664 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -3727,7 +3727,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i __START_TINY_JUMPS__(1); refdone = jit_jmpi(jit_forward()); mz_patch_branch(ref); - (void)mz_bnei_t(refslow, JIT_R0, scheme_cpointer_type, JIT_R1); + (void)mz_bnei_t(refslow, JIT_R0, scheme_cpointer_type, JIT_R2); CHECK_LIMIT(); jit_stxi_p((intptr_t)&SCHEME_CPTR_TYPE((Scheme_Object *)0x0), JIT_R0, JIT_R1); From d39801c9371c6e57cf1381637585eb53576e54ee Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Tue, 11 Aug 2015 13:06:31 -0600 Subject: [PATCH 023/381] ref_args off by one --- racket/src/racket/src/resolve.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index b3c3ec8b74..1af2c5098a 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -3401,9 +3401,9 @@ static Scheme_Object *unresolve_closure_data_2(Scheme_Closure_Data *rdata, Unres if (SCHEME_CLOSURE_DATA_FLAGS(rdata) & CLOS_HAS_TYPED_ARGS) { for (i = 0; i < data->num_params; i++) { - LOG_UNRESOLVE(printf("ref_args[%d] = %d\n", ui->stack_pos - i, + LOG_UNRESOLVE(printf("ref_args[%d] = %d\n", ui->stack_pos - i - 1, scheme_boxmap_get(rdata->closure_map, i, rdata->closure_size))); - ui->ref_args[ui->stack_pos - i] = + ui->ref_args[ui->stack_pos - i - 1] = scheme_boxmap_get(rdata->closure_map, i, rdata->closure_size); } } @@ -4065,7 +4065,7 @@ static Scheme_Sequence *unresolve_let_value(Scheme_Let_Value *lv, Unresolve_Info Scheme_Sequence *seq; LOG_UNRESOLVE(printf("set! position: %d (stack pos %d)\n", lv->position, ui->stack_pos)); - if (ui->ref_args[ui->stack_pos - lv->position]) { + if (ui->ref_args[ui->stack_pos - lv->position - 1]) { Scheme_App2_Rec *app2; var = scheme_make_local(scheme_local_type, unresolve_set_flag(ui, @@ -4123,7 +4123,7 @@ Scheme_App_Rec *maybe_unresolve_app_refs(Scheme_App_Rec *app, Unresolve_Info *ui LOG_UNRESOLVE(printf("ui->stack_pos = %d, argpos = %d, i = %d\n", ui->stack_pos, SCHEME_LOCAL_POS(app->args[i + 1]), i)); if ((scheme_boxmap_get(data->closure_map, i, data->closure_size) & CLOS_TYPE_BOXED) && SAME_TYPE(SCHEME_TYPE(app->args[i + 1]), scheme_local_type) && - !ui->ref_args[ui->stack_pos - SCHEME_LOCAL_POS(app->args[i + 1])]) { + !ui->ref_args[ui->stack_pos - SCHEME_LOCAL_POS(app->args[i + 1]) - 1]) { Scheme_Case_Lambda *cl; Scheme_Closure_Data *d0, *d1; Scheme_Set_Bang *sb; @@ -4233,7 +4233,7 @@ static Scheme_Object *unresolve_expr_2(Scheme_Object *e, Unresolve_Info *ui, int 0); case scheme_local_unbox_type: { - if (ui->ref_args[ui->stack_pos - SCHEME_LOCAL_POS(e)]) { + if (ui->ref_args[ui->stack_pos - SCHEME_LOCAL_POS(e) - 1]) { Scheme_App_Rec *app; Scheme_Object *rator; LOG_UNRESOLVE(printf("local unbox: %d (stack pos %d)\n", SCHEME_LOCAL_POS(e), ui->stack_pos)); From 956d53816458047d673f3c5ad4412be1f9cc1556 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 11 Aug 2015 15:47:42 -0600 Subject: [PATCH 024/381] fix missing zero of allocated atomic memory in unresolver --- racket/src/racket/src/resolve.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 1af2c5098a..37d88ff98c 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -3285,6 +3285,7 @@ static int unresolve_stack_push(Unresolve_Info *ui, int n, int r_only, int rev) ui->stack_size = (2 * ui->stack_size) + n; } memset(ui->flags + pos, 0, sizeof(int) * n); + memset(ui->ref_args + pos, 0, sizeof(int) * n); if (!r_only) { if (!rev) { for (i = 0; i < n; i++) { From 49dc0625d48b1c6e11179801b7b7ade22e598658 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 27 Jul 2015 15:15:18 -0400 Subject: [PATCH 025/381] more detail in openssl error --- racket/collects/openssl/mzssl.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/racket/collects/openssl/mzssl.rkt b/racket/collects/openssl/mzssl.rkt index 5ecb8b1b93..852d2cd31b 100644 --- a/racket/collects/openssl/mzssl.rkt +++ b/racket/collects/openssl/mzssl.rkt @@ -561,8 +561,11 @@ TO DO: (error 'encrypt->method "internal error, unknown encrypt: ~e" e)])) (unless f (raise (exn:fail:unsupported - (format "~a: requested protocol not supported\n requested: ~e" + (format "~a: requested protocol not supported~a\n requested: ~e" who + (if ssl-available? + "" + ";\n SSL not available; check `ssl-load-fail-reason'") e) (current-continuation-marks)))) (f)) From 6bbcbfb3d4e584d47b86b6a5fe476a4fa92b91d9 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 28 Jul 2015 17:58:31 -0400 Subject: [PATCH 026/381] fix rendering of multi-line syntax errors --- pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt b/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt index b113e941de..6febe969da 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt +++ b/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt @@ -14,7 +14,10 @@ (let ([src (ormap values (exn:fail:syntax-exprs exn))]) (if src (make-exn:fail:syntax - (format "~a at: ~s" (exn-message exn) (syntax->datum src)) + (let* ([msg (exn-message exn)] + [oneline? (not (regexp-match? #rx"\n" msg))]) + (format "~a~a at: ~s" + msg (if oneline? "" "\n ") (syntax->datum src))) (exn-continuation-marks exn) (exn:fail:syntax-exprs exn)) exn))) From 3e2b916f5be75dc2a90b4562757d45b1a6779555 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Wed, 29 Jul 2015 15:11:05 -0400 Subject: [PATCH 027/381] annotated common version list for openssl libs --- racket/collects/openssl/libcrypto.rkt | 38 +++++++++++++++++++++++---- racket/collects/openssl/libssl.rkt | 6 +---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/racket/collects/openssl/libcrypto.rkt b/racket/collects/openssl/libcrypto.rkt index a2ba657ffe..8eeefd4120 100644 --- a/racket/collects/openssl/libcrypto.rkt +++ b/racket/collects/openssl/libcrypto.rkt @@ -4,7 +4,38 @@ (for-syntax racket/base)) (provide libcrypto - libcrypto-load-fail-reason) + libcrypto-load-fail-reason + openssl-lib-versions) + +;; Notes on shared library versions when provided by OS +;; ie, VERSION s.t. OS provides "lib{crypto,ssl}.{so,dylib}.$VERSION" +;; +;; - Debian and Ubuntu use a few fixed library versions even though +;; actual OpenSSL version changes: +;; - Debian squeeze: lib{crypto,ssl}.so.0.9.8 +;; - Debian {wheezy, jessie, stretch, sid}: lib{crypto,ssl}.so.1.0.0 +;; - Ubuntu {14.04, 14.10, 15.04}: lib{crypto,ssl}.so.1.0.0 +;; - Debian and Ubuntu also provide versionless library in pkg "libssl-dev" +;; - Fedora provides libraries suffixed with actual versions (eg +;; 1.0.1k) as well as a simply-versioned symlink (eg libssl.so.10): +;; - Fedora {19, 20}: lib{crypto,ssl}.so.1.0.1e, also lib{crypto,ssl}.so.10 +;; - Fedora 21: lib{crypto,ssl}.so.1.0.1j, also lib{crypto,ssl}.so.10 +;; - Fedora 22: lib{crypto,ssl}.so.1.0.1k, also lib{crypto,ssl}.so.10 +;; - Fedora also provides a versionless library in pkg "openssl-devel" +;; - Mac OS X includes 0.9.8, 0.9.7, and versionless + +(define openssl-lib-versions + '(;; Versionless (eg from devel pkg) + "" + + ;; Compatibility-based version / SONAME + "10" ;; Fedora + "1.0.0" ;; Debian, Ubuntu + + ;; Other specific known versions + "1.0.1k" "1.0.1j" "1.0.1g" "1.0.1e" + "1.0" "1.0.0" "1.0.0e" "1.0.0d" "1.0.0c" "1.0.0b" "1.0.0a" + "0.9.8e" "0.9.8b" "0.9.8" "0.9.7")) (define libcrypto-load-fail-reason #f) @@ -19,7 +50,4 @@ (with-handlers ([exn:fail? (lambda (x) (set! libcrypto-load-fail-reason (exn-message x)) #f)]) - (ffi-lib libcrypto-so '("" - "1.0.1e" - "1.0.0" "1.0" - "0.9.8b" "0.9.8" "0.9.7")))) + (ffi-lib libcrypto-so openssl-lib-versions))) diff --git a/racket/collects/openssl/libssl.rkt b/racket/collects/openssl/libssl.rkt index 4f4dd305ba..122a346fa1 100644 --- a/racket/collects/openssl/libssl.rkt +++ b/racket/collects/openssl/libssl.rkt @@ -22,8 +22,4 @@ (lambda (x) (set! libssl-load-fail-reason (exn-message x)) #f)]) - (ffi-lib libssl-so - '("" - "1.0.1j" "1.0.1g" "1.0.1e" - "1.0" "1.0.0" "1.0.0e" "1.0.0d" "1.0.0c" "1.0.0b" "1.0.0a" - "0.9.8e" "0.9.8b" "0.9.8" "0.9.7"))))) + (ffi-lib libssl-so openssl-lib-versions)))) From a970f9bf6e22bc084e49162a542326a55148c37d Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 11 Aug 2015 21:26:07 -0400 Subject: [PATCH 028/381] Fix a few cases of "it's" instead of "its" in docs --- pkgs/racket-doc/file/scribblings/convertible.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/syntax-model.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/syntax.scrbl | 2 +- pkgs/racket-doc/syntax/scribblings/quote.scrbl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-doc/file/scribblings/convertible.scrbl b/pkgs/racket-doc/file/scribblings/convertible.scrbl index 57edc59da8..0a6c584300 100644 --- a/pkgs/racket-doc/file/scribblings/convertible.scrbl +++ b/pkgs/racket-doc/file/scribblings/convertible.scrbl @@ -31,7 +31,7 @@ should be considered standard: and eight numbers; like @racket['png-bytes+bounds], but where the image encoded that is in the byte string can be padded in each direction (to allow the drawn region to extend beyond - it's ``bounding box''), where the extra four numbers in the + its ``bounding box''), where the extra four numbers in the list specify the amount of padding that was added to the image: left, right, top, and bottom} @item{@racket['png@2x-bytes] --- like @racket['png-bytes], but for an diff --git a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl index 84c3f5c033..6ca75808ee 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl @@ -74,7 +74,7 @@ corresponds to the @racket[let] form. When a @tech{form} parses as the binding of a particular identifier, parsing updates a global table that maps a combination of an -identifier's @tech{symbol} and @tech{scope set} to it's meaning: a +identifier's @tech{symbol} and @tech{scope set} to its meaning: a @tech{variable}, a @tech{syntactic form}, or a @tech{transformer}. An identifier refers to a particular binding when the reference's symbol and the identifier's symbol are the same, and when the reference's diff --git a/pkgs/racket-doc/scribblings/reference/syntax.scrbl b/pkgs/racket-doc/scribblings/reference/syntax.scrbl index 45be6ecc66..4308848967 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax.scrbl @@ -315,7 +315,7 @@ the submodule. In that case, @racket[begin-for-syntax] forms that wrap the @racket[module*] form shift the @tech{phase level} of the enclosing module's bindings relative to the submodule. The macro expander handles such nesting by shifting the @tech{phase level} of -the @racket[module*] form so that it's body starts at @tech{phase +the @racket[module*] form so that its body starts at @tech{phase level} 0, expanding, and then reverting the @tech{phase level} shift; beware that this process can leave @tech{syntax objects} as @racket['origin] @tech{syntax property} values out-of-sync with the diff --git a/pkgs/racket-doc/syntax/scribblings/quote.scrbl b/pkgs/racket-doc/syntax/scribblings/quote.scrbl index a2dc52005e..c0e7d86912 100644 --- a/pkgs/racket-doc/syntax/scribblings/quote.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/quote.scrbl @@ -5,7 +5,7 @@ @title{Preserving Source Locations} @defmodule[syntax/quote]{The @racketmodname[syntax/quote] module -provides support for quoting syntax so that it's source locations +provides support for quoting syntax so that its source locations are preserved in marshaled bytecode form.} @defform*[[(quote-syntax/keep-srcloc datum) From 9473f394b7513211023b852098076210e70c749a Mon Sep 17 00:00:00 2001 From: Tim Brown Date: Fri, 29 May 2015 17:05:01 +0100 Subject: [PATCH 029/381] url-strings: Separate URL parsing from URL actions `net/url` provides functions for both converting strings and paths to and from URLs. `net/url` also includes functions for creating (pure and import) network ports. This functionality `require` the HTTP client stack which is unnecessary when URLs simple need parsing for their "bits". New library: `net/url-strings` handles `url->string` and `string->url` (and also the related `path->url` and `url->path` functions). This is required by net/url for compatability. `net/url-exception.rkt` is factored out for use by both libraries. - See also racket/net changes for T&D url-string.rkt changes requested by mflatt url-strings.rkt is now called url-string.rkt identifiers from url-string.rkt are reprovided by url.rkt using (all-from-out "url-string.rkt") instead of explicit exports --- racket/collects/net/url-exception.rkt | 19 ++ racket/collects/net/url-string.rkt | 400 ++++++++++++++++++++++++++ racket/collects/net/url.rkt | 391 +------------------------ 3 files changed, 425 insertions(+), 385 deletions(-) create mode 100644 racket/collects/net/url-exception.rkt create mode 100644 racket/collects/net/url-string.rkt diff --git a/racket/collects/net/url-exception.rkt b/racket/collects/net/url-exception.rkt new file mode 100644 index 0000000000..1dcff0b49c --- /dev/null +++ b/racket/collects/net/url-exception.rkt @@ -0,0 +1,19 @@ +#lang racket/base +(require racket/string + racket/contract/base + racket/list) + +(define-struct (url-exception exn:fail) ()) +(define (-url-exception? x) + (or (url-exception? x) + + ;; two of the errors that string->url can raise are + ;; now contract violations instead of url-expcetion + ;; structs. since only the url-exception? predicate + ;; was exported, we just add this in to the predicate + ;; to preserve backwards compatibility + (and (exn:fail:contract? x) + (regexp-match? #rx"^string->url:" (exn-message x))))) + +(provide (struct-out url-exception)) +(provide/contract (-url-exception? (any/c . -> . boolean?))) diff --git a/racket/collects/net/url-string.rkt b/racket/collects/net/url-string.rkt new file mode 100644 index 0000000000..77cb5560e4 --- /dev/null +++ b/racket/collects/net/url-string.rkt @@ -0,0 +1,400 @@ +#lang racket/base +(require racket/string + racket/contract/base + racket/list + "url-structs.rkt" + "url-exception.rkt" + "uri-codec.rkt") + +;; To do: +;; Handle HTTP/file errors. +;; Not throw away MIME headers. +;; Determine file type. + +(define-logger net/url) + +;; ---------------------------------------------------------------------- + +;; Input ports have two statuses: +;; "impure" = they have text waiting +;; "pure" = the MIME headers have been read + +(define file-url-path-convention-type (make-parameter (system-path-convention-type))) + +(define (url-error fmt . args) + (raise (make-url-exception + (apply format fmt + (map (lambda (arg) (if (url? arg) (url->string arg) arg)) + args)) + (current-continuation-marks)))) + +(define (url->string url) + (let ([scheme (url-scheme url)] + [user (url-user url)] + [host (url-host url)] + [port (url-port url)] + [path (url-path url)] + [query (url-query url)] + [fragment (url-fragment url)] + [sa list] + [sa* (lambda (l) + (apply string-append + (let loop ([l l]) + (cond + [(null? l) l] + [(pair? (car l)) + (append (loop (car l)) + (loop (cdr l)))] + [(null? (car l)) (loop (cdr l))] + [else (cons (car l) (loop (cdr l)))]))))]) + (when (and (equal? scheme "file") + (not (url-path-absolute? url))) + (raise-mismatch-error 'url->string + "cannot convert relative file URL to a string: " + url)) + (sa* + (append + (if scheme (sa scheme ":") null) + (if (or user host port) + (sa "//" + (if user (sa (uri-userinfo-encode user) "@") null) + (if host host null) + (if port (sa ":" (number->string port)) null)) + (if (equal? "file" scheme) ; always need "//" for "file" URLs + '("//") + null)) + (combine-path-strings (url-path-absolute? url) path) + ;; (if query (sa "?" (uri-encode query)) "") + (if (null? query) null (sa "?" (alist->form-urlencoded query))) + (if fragment (sa "#" (uri-encode* fragment)) null))))) + +;; transliteration of code in rfc 3986, section 5.2.2 +(define (combine-url/relative Base string) + (let ([R (string->url string)] + [T (make-url #f #f #f #f #f '() '() #f)]) + (if (url-scheme R) + (begin + (set-url-scheme! T (url-scheme R)) + (set-url-user! T (url-user R)) ;; authority + (set-url-host! T (url-host R)) ;; authority + (set-url-port! T (url-port R)) ;; authority + (set-url-path-absolute?! T (url-path-absolute? R)) + (set-url-path! T (remove-dot-segments (url-path R))) + (set-url-query! T (url-query R))) + (begin + (if (url-host R) ;; => authority is defined + (begin + (set-url-user! T (url-user R)) ;; authority + (set-url-host! T (url-host R)) ;; authority + (set-url-port! T (url-port R)) ;; authority + (set-url-path-absolute?! T (url-path-absolute? R)) + (set-url-path! T (remove-dot-segments (url-path R))) + (set-url-query! T (url-query R))) + (begin + (if (null? (url-path R)) ;; => R has empty path + (begin + (set-url-path-absolute?! T (url-path-absolute? Base)) + (set-url-path! T (url-path Base)) + (if (not (null? (url-query R))) + (set-url-query! T (url-query R)) + (set-url-query! T (url-query Base)))) + (begin + (cond + [(url-path-absolute? R) + (set-url-path-absolute?! T #t) + (set-url-path! T (remove-dot-segments (url-path R)))] + [(and (null? (url-path Base)) + (url-host Base)) + (set-url-path-absolute?! T #t) + (set-url-path! T (remove-dot-segments (url-path R)))] + [else + (set-url-path-absolute?! T (url-path-absolute? Base)) + (set-url-path! T (remove-dot-segments + (append (all-but-last (url-path Base)) + (url-path R))))]) + (set-url-query! T (url-query R)))) + (set-url-user! T (url-user Base)) ;; authority + (set-url-host! T (url-host Base)) ;; authority + (set-url-port! T (url-port Base)))) ;; authority + (set-url-scheme! T (url-scheme Base)))) + (set-url-fragment! T (url-fragment R)) + T)) + +(define (all-but-last lst) + (cond [(null? lst) null] + [(null? (cdr lst)) null] + [else (cons (car lst) (all-but-last (cdr lst)))])) + +;; cribbed from 5.2.4 in rfc 3986 +;; the strange [*] cases implicitly change urls +;; with paths segments "." and ".." at the end +;; into "./" and "../" respectively +(define (remove-dot-segments path) + (let loop ([path path] [result '()]) + (if (null? path) + (reverse result) + (let ([fst (path/param-path (car path))] + [rst (cdr path)]) + (loop rst + (cond + [(and (eq? fst 'same) (null? rst)) + (cons (make-path/param "" '()) result)] ; [*] + [(eq? fst 'same) + result] + [(and (eq? fst 'up) (null? rst) (not (null? result))) + (cons (make-path/param "" '()) (cdr result))] ; [*] + [(and (eq? fst 'up) (not (null? result))) + (cdr result)] + [(and (eq? fst 'up) (null? result)) + ;; when we go up too far, just drop the "up"s. + result] + [else + (cons (car path) result)])))))) + +;; netscape/string->url : str -> url +(define (netscape/string->url string) + (let ([url (string->url string)]) + (cond [(url-scheme url) url] + [(string=? string "") + (url-error "Can't resolve empty string as URL")] + [else (set-url-scheme! url + (if (char=? (string-ref string 0) #\/) "file" "http")) + url]))) + +;; URL parsing regexp +;; this is following the regexp in Appendix B of rfc 3986, except for using +;; `*' instead of `+' for the scheme part (it is checked later anyway, and +;; we don't want to parse it as a path element), and the user@host:port is +;; parsed here. +(define url-regexp + (regexp (string-append + "^" + "(?:" ; / scheme-colon-opt + "([^:/?#]*)" ; | #1 = scheme-opt + ":)?" ; \ + "(?://" ; / slash-slash-authority-opt + "(?:" ; | / user-at-opt + "([^/?#@]*)" ; | | #2 = user-opt + "@)?" ; | \ + "([^/?#:]*)?" ; | #3 = host-opt + "(?::" ; | / colon-port-opt + "([0-9]*)" ; | | #4 = port-opt + ")?" ; | \ + ")?" ; \ + "([^?#]*)" ; #5 = path + "(?:\\?" ; / question-query-opt + "([^#]*)" ; | #6 = query-opt + ")?" ; \ + "(?:#" ; / hash-fragment-opt + "(.*)" ; | #7 = fragment-opt + ")?" ; \ + "$"))) + +;; string->url : str -> url +;; Original version by Neil Van Dyke +(define (string->url str) + (apply + (lambda (scheme user host port path query fragment) + (when (and scheme (not (regexp-match? #rx"^[a-zA-Z][a-zA-Z0-9+.-]*$" + scheme))) + (url-error "Invalid URL string; bad scheme ~e: ~e" scheme str)) + ;; Windows => "file://xxx:/...." specifies a "xxx:/..." path + (let ([win-file? (and (or (equal? "" port) (not port)) + (equal? "file" scheme) + (eq? 'windows (file-url-path-convention-type)) + (not (equal? host "")))]) + (when win-file? + (set! path (cond [(equal? "" port) (string-append host ":" path)] + [(and path host) (string-append host "/" path)] + [else (or path host)])) + (set! port #f) + (set! host "")) + (let* ([scheme (and scheme (string-downcase scheme))] + [host (and host (string-downcase host))] + [user (uri-decode/maybe user)] + [port (and port (string->number port))] + [abs? (or (equal? "file" scheme) + (regexp-match? #rx"^/" path))] + [path (if win-file? + (separate-windows-path-strings path) + (separate-path-strings path))] + [query (if query (form-urlencoded->alist query) '())] + [fragment (uri-decode/maybe fragment)]) + (make-url scheme user host port abs? path query fragment)))) + (cdr (regexp-match url-regexp str)))) + +(define (uri-decode/maybe f) (friendly-decode/maybe f uri-decode)) + +(define (friendly-decode/maybe f uri-decode) + ;; If #f, and leave unmolested any % that is followed by hex digit + ;; if a % is not followed by a hex digit, replace it with %25 + ;; in an attempt to be "friendly" + (and f (uri-decode (regexp-replace* #rx"%([^0-9a-fA-F])" f "%25\\1")))) + +;; separate-path-strings : string[starting with /] -> (listof path/param) +(define (separate-path-strings str) + (let ([strs (regexp-split #rx"/" str)]) + (map separate-params (if (string=? "" (car strs)) (cdr strs) strs)))) + +(define (separate-windows-path-strings str) + (url-path (path->url (bytes->path (string->bytes/utf-8 str) 'windows)))) + +(define (separate-params s) + (let ([lst (map path-segment-decode (regexp-split #rx";" s))]) + (make-path/param (car lst) (cdr lst)))) + +(define (path-segment-decode p) + (cond [(string=? p "..") 'up] + [(string=? p ".") 'same] + [else (uri-path-segment-decode p)])) + +(define (path-segment-encode p) + (cond [(eq? p 'up) ".."] + [(eq? p 'same) "."] + [(equal? p "..") "%2e%2e"] + [(equal? p ".") "%2e"] + [else (uri-path-segment-encode* p)])) + +(define (combine-path-strings absolute? path/params) + (cond [(null? path/params) null] + [else (let ([p (add-between (map join-params path/params) "/")]) + (if absolute? (cons "/" p) p))])) + +(define (join-params s) + (if (null? (path/param-param s)) + (path-segment-encode (path/param-path s)) + (string-join (map path-segment-encode + (cons (path/param-path s) (path/param-param s))) + ";"))) + +(define (path->url path) + (let* ([spath (simplify-path path #f)] + [dir? (let-values ([(b n dir?) (split-path spath)]) dir?)] + ;; If original path is a directory the resulting URL + ;; should have a trailing forward slash + [url-tail (if dir? (list (make-path/param "" null)) null)] + [url-path + (let loop ([path spath][accum null]) + (let-values ([(base name dir?) (split-path path)]) + (cond + [(not base) + (if (eq? (path-convention-type path) 'windows) + ;; For Windows, massage the root: + (append (map + (lambda (s) + (make-path/param s null)) + (let ([s (regexp-replace + #rx"[/\\\\]$" + (bytes->string/utf-8 (path->bytes name)) + "")]) + (cond + [(regexp-match? #rx"^\\\\\\\\[?]\\\\[a-zA-Z]:" s) + ;; \\?\: path: + (regexp-split #rx"[/\\]+" (substring s 4))] + [(regexp-match? #rx"^\\\\\\\\[?]\\\\UNC" s) + ;; \\?\ UNC path: + (regexp-split #rx"[/\\]+" (substring s 7))] + [(regexp-match? #rx"^[/\\]" s) + ;; UNC path: + (regexp-split #rx"[/\\]+" s)] + [else + (list s)]))) + accum) + ;; On other platforms, we drop the root: + accum)] + [else + (let ([accum (cons (make-path/param + (if (symbol? name) + name + (bytes->string/utf-8 + (path-element->bytes name))) + null) + accum)]) + (if (eq? base 'relative) + accum + (loop base accum)))])))]) + (make-url "file" #f "" #f (absolute-path? path) + (if (null? url-tail) url-path (append url-path url-tail)) + '() #f))) + +(define (file://->path url [kind (system-path-convention-type)]) + (let ([strs (map path/param-path (url-path url))] + [string->path-element/same + (lambda (e) + (if (symbol? e) + e + (if (string=? e "") + 'same + (bytes->path-element (string->bytes/locale e) kind))))] + [string->path/win (lambda (s) + (bytes->path (string->bytes/utf-8 s) 'windows))]) + (if (and (url-path-absolute? url) + (eq? 'windows kind)) + ;; If initial path is "", then build UNC path. + (cond + [(not (url-path-absolute? url)) + (apply build-path (map string->path-element/same strs))] + [(and ((length strs) . >= . 3) + (equal? (car strs) "")) + (apply build-path + (string->path/win + (string-append "\\\\" (cadr strs) "\\" (caddr strs) "\\")) + (map string->path-element/same (cdddr strs)))] + [(pair? strs) + (apply build-path (string->path/win (car strs)) + (map string->path-element/same (cdr strs)))] + [else (error 'file://->path "no path elements: ~e" url)]) + (let ([elems (map string->path-element/same strs)]) + (if (url-path-absolute? url) + (apply build-path (bytes->path #"/" 'unix) elems) + (apply build-path elems)))))) + +(define (url->path url [kind (system-path-convention-type)]) + (file://->path url kind)) + +(define (relative-path->relative-url-string path) + (define s (string-join (for/list ([e (in-list (explode-path path))]) + (cond + [(eq? e 'same) "."] + [(eq? e 'up) ".."] + [else + (uri-encode* (path-element->string e))])) + "/")) + ;; Add "/" to reflect directory-ness: + (let-values ([(base name dir?) (split-path path)]) + (if dir? + (string-append s "/") + s))) + +(define current-url-encode-mode (make-parameter 'recommended)) + +(define (uri-encode* str) + (case (current-url-encode-mode) + [(unreserved) (uri-unreserved-encode str)] + [(recommended) (uri-encode str)])) + +(define (uri-path-segment-encode* str) + (case (current-url-encode-mode) + [(unreserved) (uri-path-segment-unreserved-encode str)] + [(recommended) (uri-path-segment-encode str)])) + +(provide (struct-out url) (struct-out path/param)) + +(provide/contract + (string->url (-> (and/c string? + (or/c #rx"^[a-zA-Z][a-zA-Z0-9+.-]*:" + (not/c #rx"^[^:/?#]*:"))) + url?)) + (path->url ((or/c path-string? path-for-some-system?) . -> . url?)) + (relative-path->relative-url-string ((and/c (or/c path-string? path-for-some-system?) + relative-path?) + . -> . string?)) + (url->string (url? . -> . string?)) + (url->path (->* (url?) ((one-of/c 'unix 'windows)) path-for-some-system?)) + (file://->path (->* (url?) ((one-of/c 'unix 'windows)) path-for-some-system?)) + (netscape/string->url (string? . -> . url?)) + (combine-url/relative (url? string? . -> . url?)) + (rename -url-exception? url-exception? (any/c . -> . boolean?)) + (file-url-path-convention-type + (parameter/c (one-of/c 'unix 'windows))) + (current-url-encode-mode (parameter/c (one-of/c 'recommended 'unreserved)))) diff --git a/racket/collects/net/url.rkt b/racket/collects/net/url.rkt index b479c967e3..c299c40d0a 100644 --- a/racket/collects/net/url.rkt +++ b/racket/collects/net/url.rkt @@ -6,8 +6,9 @@ racket/match (prefix-in hc: "http-client.rkt") (only-in "url-connect.rkt" current-https-protocol) - "url-structs.rkt" - "uri-codec.rkt") + "uri-codec.rkt" + "url-string.rkt" + (only-in "url-exception.rkt" make-url-exception)) ;; To do: ;; Handle HTTP/file errors. @@ -22,20 +23,6 @@ ;; "impure" = they have text waiting ;; "pure" = the MIME headers have been read -(define-struct (url-exception exn:fail) ()) -(define (-url-exception? x) - (or (url-exception? x) - - ;; two of the errors that string->url can raise are - ;; now contract violations instead of url-expcetion - ;; structs. since only the url-exception? predicate - ;; was exported, we just add this in to the predicate - ;; to preserve backwards compatibility - (and (exn:fail:contract? x) - (regexp-match? #rx"^string->url:" (exn-message x))))) - -(define file-url-path-convention-type (make-parameter (system-path-convention-type))) - (define current-proxy-servers (make-parameter null (lambda (v) @@ -65,46 +52,6 @@ args)) (current-continuation-marks)))) -(define (url->string url) - (let ([scheme (url-scheme url)] - [user (url-user url)] - [host (url-host url)] - [port (url-port url)] - [path (url-path url)] - [query (url-query url)] - [fragment (url-fragment url)] - [sa list] - [sa* (lambda (l) - (apply string-append - (let loop ([l l]) - (cond - [(null? l) l] - [(pair? (car l)) - (append (loop (car l)) - (loop (cdr l)))] - [(null? (car l)) (loop (cdr l))] - [else (cons (car l) (loop (cdr l)))]))))]) - (when (and (equal? scheme "file") - (not (url-path-absolute? url))) - (raise-mismatch-error 'url->string - "cannot convert relative file URL to a string: " - url)) - (sa* - (append - (if scheme (sa scheme ":") null) - (if (or user host port) - (sa "//" - (if user (sa (uri-userinfo-encode user) "@") null) - (if host host null) - (if port (sa ":" (number->string port)) null)) - (if (equal? "file" scheme) ; always need "//" for "file" URLs - '("//") - null)) - (combine-path-strings (url-path-absolute? url) path) - ;; (if query (sa "?" (uri-encode query)) "") - (if (null? query) null (sa "?" (alist->form-urlencoded query))) - (if fragment (sa "#" (uri-encode* fragment)) null))))) - ;; url->default-port : url -> num (define (url->default-port url) (let ([scheme (url-scheme url)]) @@ -151,38 +98,6 @@ #:data post-data) hc) -(define (file://->path url [kind (system-path-convention-type)]) - (let ([strs (map path/param-path (url-path url))] - [string->path-element/same - (lambda (e) - (if (symbol? e) - e - (if (string=? e "") - 'same - (bytes->path-element (string->bytes/locale e) kind))))] - [string->path/win (lambda (s) - (bytes->path (string->bytes/utf-8 s) 'windows))]) - (if (and (url-path-absolute? url) - (eq? 'windows kind)) - ;; If initial path is "", then build UNC path. - (cond - [(not (url-path-absolute? url)) - (apply build-path (map string->path-element/same strs))] - [(and ((length strs) . >= . 3) - (equal? (car strs) "")) - (apply build-path - (string->path/win - (string-append "\\\\" (cadr strs) "\\" (caddr strs) "\\")) - (map string->path-element/same (cdddr strs)))] - [(pair? strs) - (apply build-path (string->path/win (car strs)) - (map string->path-element/same (cdr strs)))] - [else (error 'file://->path "no path elements: ~e" url)]) - (let ([elems (map string->path-element/same strs)]) - (if (url-path-absolute? url) - (apply build-path (bytes->path #"/" 'unix) elems) - (apply build-path elems)))))) - ;; file://get-pure-port : url -> in-port (define (file://get-pure-port url) (open-input-file (file://->path url))) @@ -319,89 +234,6 @@ (copy-port server->client (current-output-port)) (close-input-port server->client)) -;; transliteration of code in rfc 3986, section 5.2.2 -(define (combine-url/relative Base string) - (let ([R (string->url string)] - [T (make-url #f #f #f #f #f '() '() #f)]) - (if (url-scheme R) - (begin - (set-url-scheme! T (url-scheme R)) - (set-url-user! T (url-user R)) ;; authority - (set-url-host! T (url-host R)) ;; authority - (set-url-port! T (url-port R)) ;; authority - (set-url-path-absolute?! T (url-path-absolute? R)) - (set-url-path! T (remove-dot-segments (url-path R))) - (set-url-query! T (url-query R))) - (begin - (if (url-host R) ;; => authority is defined - (begin - (set-url-user! T (url-user R)) ;; authority - (set-url-host! T (url-host R)) ;; authority - (set-url-port! T (url-port R)) ;; authority - (set-url-path-absolute?! T (url-path-absolute? R)) - (set-url-path! T (remove-dot-segments (url-path R))) - (set-url-query! T (url-query R))) - (begin - (if (null? (url-path R)) ;; => R has empty path - (begin - (set-url-path-absolute?! T (url-path-absolute? Base)) - (set-url-path! T (url-path Base)) - (if (not (null? (url-query R))) - (set-url-query! T (url-query R)) - (set-url-query! T (url-query Base)))) - (begin - (cond - [(url-path-absolute? R) - (set-url-path-absolute?! T #t) - (set-url-path! T (remove-dot-segments (url-path R)))] - [(and (null? (url-path Base)) - (url-host Base)) - (set-url-path-absolute?! T #t) - (set-url-path! T (remove-dot-segments (url-path R)))] - [else - (set-url-path-absolute?! T (url-path-absolute? Base)) - (set-url-path! T (remove-dot-segments - (append (all-but-last (url-path Base)) - (url-path R))))]) - (set-url-query! T (url-query R)))) - (set-url-user! T (url-user Base)) ;; authority - (set-url-host! T (url-host Base)) ;; authority - (set-url-port! T (url-port Base)))) ;; authority - (set-url-scheme! T (url-scheme Base)))) - (set-url-fragment! T (url-fragment R)) - T)) - -(define (all-but-last lst) - (cond [(null? lst) null] - [(null? (cdr lst)) null] - [else (cons (car lst) (all-but-last (cdr lst)))])) - -;; cribbed from 5.2.4 in rfc 3986 -;; the strange [*] cases implicitly change urls -;; with paths segments "." and ".." at the end -;; into "./" and "../" respectively -(define (remove-dot-segments path) - (let loop ([path path] [result '()]) - (if (null? path) - (reverse result) - (let ([fst (path/param-path (car path))] - [rst (cdr path)]) - (loop rst - (cond - [(and (eq? fst 'same) (null? rst)) - (cons (make-path/param "" '()) result)] ; [*] - [(eq? fst 'same) - result] - [(and (eq? fst 'up) (null? rst) (not (null? result))) - (cons (make-path/param "" '()) (cdr result))] ; [*] - [(and (eq? fst 'up) (not (null? result))) - (cdr result)] - [(and (eq? fst 'up) (null? result)) - ;; when we go up too far, just drop the "up"s. - result] - [else - (cons (car path) result)])))))) - ;; call/input-url : url x (url -> in-port) x (in-port -> T) ;; [x list (str)] -> T (define call/input-url @@ -427,189 +259,6 @@ (purify-port in-port) in-port) -;; netscape/string->url : str -> url -(define (netscape/string->url string) - (let ([url (string->url string)]) - (cond [(url-scheme url) url] - [(string=? string "") - (url-error "Can't resolve empty string as URL")] - [else (set-url-scheme! url - (if (char=? (string-ref string 0) #\/) "file" "http")) - url]))) - -;; URL parsing regexp -;; this is following the regexp in Appendix B of rfc 3986, except for using -;; `*' instead of `+' for the scheme part (it is checked later anyway, and -;; we don't want to parse it as a path element), and the user@host:port is -;; parsed here. -(define url-regexp - (regexp (string-append - "^" - "(?:" ; / scheme-colon-opt - "([^:/?#]*)" ; | #1 = scheme-opt - ":)?" ; \ - "(?://" ; / slash-slash-authority-opt - "(?:" ; | / user-at-opt - "([^/?#@]*)" ; | | #2 = user-opt - "@)?" ; | \ - "([^/?#:]*)?" ; | #3 = host-opt - "(?::" ; | / colon-port-opt - "([0-9]*)" ; | | #4 = port-opt - ")?" ; | \ - ")?" ; \ - "([^?#]*)" ; #5 = path - "(?:\\?" ; / question-query-opt - "([^#]*)" ; | #6 = query-opt - ")?" ; \ - "(?:#" ; / hash-fragment-opt - "(.*)" ; | #7 = fragment-opt - ")?" ; \ - "$"))) - -;; string->url : str -> url -;; Original version by Neil Van Dyke -(define (string->url str) - (apply - (lambda (scheme user host port path query fragment) - (when (and scheme (not (regexp-match? #rx"^[a-zA-Z][a-zA-Z0-9+.-]*$" - scheme))) - (url-error "Invalid URL string; bad scheme ~e: ~e" scheme str)) - ;; Windows => "file://xxx:/...." specifies a "xxx:/..." path - (let ([win-file? (and (or (equal? "" port) (not port)) - (equal? "file" scheme) - (eq? 'windows (file-url-path-convention-type)) - (not (equal? host "")))]) - (when win-file? - (set! path (cond [(equal? "" port) (string-append host ":" path)] - [(and path host) (string-append host "/" path)] - [else (or path host)])) - (set! port #f) - (set! host "")) - (let* ([scheme (and scheme (string-downcase scheme))] - [host (and host (string-downcase host))] - [user (uri-decode/maybe user)] - [port (and port (string->number port))] - [abs? (or (equal? "file" scheme) - (regexp-match? #rx"^/" path))] - [path (if win-file? - (separate-windows-path-strings path) - (separate-path-strings path))] - [query (if query (form-urlencoded->alist query) '())] - [fragment (uri-decode/maybe fragment)]) - (make-url scheme user host port abs? path query fragment)))) - (cdr (regexp-match url-regexp str)))) - -(define (uri-decode/maybe f) (friendly-decode/maybe f uri-decode)) - -(define (friendly-decode/maybe f uri-decode) - ;; If #f, and leave unmolested any % that is followed by hex digit - ;; if a % is not followed by a hex digit, replace it with %25 - ;; in an attempt to be "friendly" - (and f (uri-decode (regexp-replace* #rx"%([^0-9a-fA-F])" f "%25\\1")))) - -;; separate-path-strings : string[starting with /] -> (listof path/param) -(define (separate-path-strings str) - (let ([strs (regexp-split #rx"/" str)]) - (map separate-params (if (string=? "" (car strs)) (cdr strs) strs)))) - -(define (separate-windows-path-strings str) - (url-path (path->url (bytes->path (string->bytes/utf-8 str) 'windows)))) - -(define (separate-params s) - (let ([lst (map path-segment-decode (regexp-split #rx";" s))]) - (make-path/param (car lst) (cdr lst)))) - -(define (path-segment-decode p) - (cond [(string=? p "..") 'up] - [(string=? p ".") 'same] - [else (uri-path-segment-decode p)])) - -(define (path-segment-encode p) - (cond [(eq? p 'up) ".."] - [(eq? p 'same) "."] - [(equal? p "..") "%2e%2e"] - [(equal? p ".") "%2e"] - [else (uri-path-segment-encode* p)])) - -(define (combine-path-strings absolute? path/params) - (cond [(null? path/params) null] - [else (let ([p (add-between (map join-params path/params) "/")]) - (if absolute? (cons "/" p) p))])) - -(define (join-params s) - (if (null? (path/param-param s)) - (path-segment-encode (path/param-path s)) - (string-join (map path-segment-encode - (cons (path/param-path s) (path/param-param s))) - ";"))) - -(define (path->url path) - (let* ([spath (simplify-path path #f)] - [dir? (let-values ([(b n dir?) (split-path spath)]) dir?)] - ;; If original path is a directory the resulting URL - ;; should have a trailing forward slash - [url-tail (if dir? (list (make-path/param "" null)) null)] - [url-path - (let loop ([path spath][accum null]) - (let-values ([(base name dir?) (split-path path)]) - (cond - [(not base) - (if (eq? (path-convention-type path) 'windows) - ;; For Windows, massage the root: - (append (map - (lambda (s) - (make-path/param s null)) - (let ([s (regexp-replace - #rx"[/\\\\]$" - (bytes->string/utf-8 (path->bytes name)) - "")]) - (cond - [(regexp-match? #rx"^\\\\\\\\[?]\\\\[a-zA-Z]:" s) - ;; \\?\: path: - (regexp-split #rx"[/\\]+" (substring s 4))] - [(regexp-match? #rx"^\\\\\\\\[?]\\\\UNC" s) - ;; \\?\ UNC path: - (regexp-split #rx"[/\\]+" (substring s 7))] - [(regexp-match? #rx"^[/\\]" s) - ;; UNC path: - (regexp-split #rx"[/\\]+" s)] - [else - (list s)]))) - accum) - ;; On other platforms, we drop the root: - accum)] - [else - (let ([accum (cons (make-path/param - (if (symbol? name) - name - (bytes->string/utf-8 - (path-element->bytes name))) - null) - accum)]) - (if (eq? base 'relative) - accum - (loop base accum)))])))]) - (make-url "file" #f "" #f (absolute-path? path) - (if (null? url-tail) url-path (append url-path url-tail)) - '() #f))) - -(define (relative-path->relative-url-string path) - (define s (string-join (for/list ([e (in-list (explode-path path))]) - (cond - [(eq? e 'same) "."] - [(eq? e 'up) ".."] - [else - (uri-encode* (path-element->string e))])) - "/")) - ;; Add "/" to reflect directory-ness: - (let-values ([(base name dir?) (split-path path)]) - (if dir? - (string-append s "/") - s))) - -(define (url->path url [kind (system-path-convention-type)]) - (file://->path url kind)) - ;; delete-pure-port : url [x list (str)] -> in-port (define (delete-pure-port url [strings '()]) (method-pure-port 'delete url #f strings)) @@ -689,32 +338,9 @@ #:data data) (http-conn-impure-port hc))) -(define current-url-encode-mode (make-parameter 'recommended)) - -(define (uri-encode* str) - (case (current-url-encode-mode) - [(unreserved) (uri-unreserved-encode str)] - [(recommended) (uri-encode str)])) - -(define (uri-path-segment-encode* str) - (case (current-url-encode-mode) - [(unreserved) (uri-path-segment-unreserved-encode str)] - [(recommended) (uri-path-segment-encode str)])) - -(provide (struct-out url) (struct-out path/param)) +(provide (all-from-out "url-string.rkt")) (provide/contract - (string->url (-> (and/c string? - (or/c #rx"^[a-zA-Z][a-zA-Z0-9+.-]*:" - (not/c #rx"^[^:/?#]*:"))) - url?)) - (path->url ((or/c path-string? path-for-some-system?) . -> . url?)) - (relative-path->relative-url-string ((and/c (or/c path-string? path-for-some-system?) - relative-path?) - . -> . string?)) - (url->string (url? . -> . string?)) - (url->path (->* (url?) ((one-of/c 'unix 'windows)) path-for-some-system?)) - (get-pure-port (->* (url?) ((listof string?) #:redirections exact-nonnegative-integer?) input-port?)) (get-impure-port (->* (url?) ((listof string?)) input-port?)) (post-pure-port (->* (url? (or/c false/c bytes?)) ((listof string?)) input-port?)) @@ -738,7 +364,6 @@ (rename hc:http-conn? http-connection? (any/c . -> . boolean?)) (make-http-connection (-> hc:http-conn?)) (http-connection-close (hc:http-conn? . -> . void?)) - (netscape/string->url (string? . -> . url?)) (call/input-url (case-> (-> url? (-> url? input-port?) (-> input-port? any) @@ -748,13 +373,9 @@ (-> input-port? any) (listof string?) any))) - (combine-url/relative (url? string? . -> . url?)) - (rename -url-exception? url-exception? (any/c . -> . boolean?)) + (url-exception? (any/c . -> . boolean?)) (current-proxy-servers - (parameter/c (or/c false/c (listof (list/c string? string? number?))))) - (file-url-path-convention-type - (parameter/c (one-of/c 'unix 'windows))) - (current-url-encode-mode (parameter/c (one-of/c 'recommended 'unreserved)))) + (parameter/c (or/c false/c (listof (list/c string? string? number?)))))) (define (http-sendrecv/url u #:method [method-bss #"GET"] From 3f53d214c68250f21372626c15d582130fd1bd76 Mon Sep 17 00:00:00 2001 From: Tim Brown Date: Tue, 21 Jul 2015 10:05:55 +0100 Subject: [PATCH 030/381] url-exception? exported wrongly --- racket/collects/net/url.rkt | 1 - 1 file changed, 1 deletion(-) diff --git a/racket/collects/net/url.rkt b/racket/collects/net/url.rkt index c299c40d0a..2a39e39085 100644 --- a/racket/collects/net/url.rkt +++ b/racket/collects/net/url.rkt @@ -373,7 +373,6 @@ (-> input-port? any) (listof string?) any))) - (url-exception? (any/c . -> . boolean?)) (current-proxy-servers (parameter/c (or/c false/c (listof (list/c string? string? number?)))))) From 02574d25016b2cc2c988c0358071a6b3e6647b1f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 12 Aug 2015 14:40:51 -0600 Subject: [PATCH 031/381] SGC: use PRIdPTR and PRIxPTR Avoid compiler warnings by using the right format string. --- racket/src/racket/sgc/Makefile.in | 5 +- racket/src/racket/sgc/sgc.c | 104 +++++++++++++++--------------- racket/src/racket/src/Makefile.in | 2 +- racket/src/racket/src/schpriv.h | 8 +-- racket/src/racket/utils/schiptr.h | 8 +++ 5 files changed, 67 insertions(+), 60 deletions(-) create mode 100644 racket/src/racket/utils/schiptr.h diff --git a/racket/src/racket/sgc/Makefile.in b/racket/src/racket/sgc/Makefile.in index 969c8229fa..0de1b5a28f 100644 --- a/racket/src/racket/sgc/Makefile.in +++ b/racket/src/racket/sgc/Makefile.in @@ -35,7 +35,10 @@ test: $(OBJS) test.@LTO@ gcobjects: $(OBJS) -sgc.@LTO@: $(srcdir)/sgc.c $(srcdir)/autostat.inc $(srcdir)/collect.inc $(srcdir)/../utils/splay.c +EXTRA_DEPS = $(srcdir)/autostat.inc $(srcdir)/collect.inc \ + $(srcdir)/../utils/splay.c $(srcdir)/../utils/schiptr.h + +sgc.@LTO@: $(srcdir)/sgc.c $(EXTRA_DEPS) $(CC) $(CFLAGS) $(CPPFLAGS) @OPTIONS@ -DSGC_EXPORTS -I.. -c $(srcdir)/sgc.c -o sgc.@LTO@ test.@LTO@: $(srcdir)/test.c diff --git a/racket/src/racket/sgc/sgc.c b/racket/src/racket/sgc/sgc.c index 228355119b..9739a4a8f4 100644 --- a/racket/src/racket/sgc/sgc.c +++ b/racket/src/racket/sgc/sgc.c @@ -50,6 +50,8 @@ # endif #endif +#include "../utils/schiptr.h" + /****************************************************************************/ /* Option bundles */ /****************************************************************************/ @@ -2023,15 +2025,15 @@ void GC_dump(void) FPRINTF(STDERR, "Begin Map\n"); FPRINTF(STDERR, - "allocated: %ld collectable: %ld uncollectable: %ld\n" - "including known overhead: %ld scheduled gc: %ld last collect depth: %ld\n" - "managed: %ld managed including overhead: %ld\n" - "sector used: %ld sector free: %ld sector total: %ld\n" - "sector range: %ld sector administration: %ld\n" - "num sector allocs: %ld num sector frees: %ld\n" + "allocated: %"PRIdPTR" collectable: %"PRIdPTR" uncollectable: %"PRIdPTR"\n" + "including known overhead: %"PRIdPTR" scheduled gc: %"PRIdPTR" last collect depth: %"PRIdPTR"\n" + "managed: %"PRIdPTR" managed including overhead: %"PRIdPTR"\n" + "sector used: %"PRIdPTR" sector free: %"PRIdPTR" sector total: %"PRIdPTR"\n" + "sector range: %"PRIdPTR" sector administration: %"PRIdPTR"\n" + "num sector allocs: %"PRIdPTR" num sector frees: %"PRIdPTR"\n" "num disappearing links: %d num finalizations: %d queued: %d\n" #if STAMP_AND_REMEMBER_SOURCE - "current clock: %ld\n" + "current clock: %"PRIdPTR"\n" #endif , mem_use + mem_uncollectable_use, mem_use, mem_uncollectable_use, mem_real_use, mem_limit, collect_mem_use, @@ -2058,11 +2060,11 @@ void GC_dump(void) #if DUMP_BLOCK_MAPS FPRINTF(STDERR, "roots: ======================================\n"); for (i = 0; i < roots_count; i += 2) - FPRINTF(STDERR, ">%lx-%lx", roots[i], roots[i + 1]); + FPRINTF(STDERR, ">%"PRIxPTR"-%"PRIxPTR"", roots[i], roots[i + 1]); FPRINTF(STDERR, "\n"); FPRINTF(STDERR, "stack: ======================================\n"); - FPRINTF(STDERR, ">%lx-%lx>%lx-%lx\n", + FPRINTF(STDERR, ">%"PRIxPTR"-%"PRIxPTR">%"PRIxPTR"-%"PRIxPTR"\n", trace_stack_start, trace_stack_end, trace_reg_start, trace_reg_end); #endif @@ -2087,7 +2089,7 @@ void GC_dump(void) FPRINTF(STDERR, "%d:", block->size); #if DUMP_BLOCK_MAPS - FPRINTF(STDERR, "[%lx]", block->start - (uintptr_t)block); + FPRINTF(STDERR, "[%"PRIxPTR"]", block->start - (uintptr_t)block); #endif while (block) { @@ -2109,9 +2111,9 @@ void GC_dump(void) #if DUMP_BLOCK_MAPS FPRINTF(STDERR, - ">%lxx%d" + ">%"PRIxPTR"x%d" #if STAMP_AND_REMEMBER_SOURCE - "@%ld-%ld:%lx-%lx" + "@%"PRIdPTR"-%"PRIdPTR":%"PRIxPTR"-%"PRIxPTR"" #endif , (uintptr_t)block, counter #if STAMP_AND_REMEMBER_SOURCE @@ -2139,10 +2141,10 @@ void GC_dump(void) for (c = *(cs->othersptr); c; c = cnext) { uintptr_t size = c->end - c->start; - FPRINTF(STDERR, "%ld:", size); + FPRINTF(STDERR, "%"PRIdPTR":", size); #if DUMP_BLOCK_MAPS - FPRINTF(STDERR, "[%lx]", c->start - (uintptr_t)c); + FPRINTF(STDERR, "[%"PRIxPTR"]", c->start - (uintptr_t)c); #endif cnext = c->next; @@ -2154,9 +2156,9 @@ void GC_dump(void) if (size == (t->end - t->start)) { #if DUMP_BLOCK_MAPS FPRINTF(STDERR, - ">%lx" + ">%"PRIxPTR"" #if STAMP_AND_REMEMBER_SOURCE - "@%ld:%lx" + "@%"PRIdPTR":%"PRIxPTR"" #endif , (uintptr_t)t #if STAMP_AND_REMEMBER_SOURCE @@ -2207,7 +2209,7 @@ void GC_dump(void) } #endif - FPRINTF(STDERR, "total size: %ld\n", total); + FPRINTF(STDERR, "total size: %"PRIdPTR"\n", total); } FPRINTF(STDERR, "summary: ======================================\n"); @@ -2215,13 +2217,13 @@ void GC_dump(void) for (j = 0; j < num_common_sets; j++) { GC_Set *cs = common_sets[j]; FPRINTF(STDERR, - "%12s: %10ld [%s/%s]\n", + "%12s: %10"PRIdPTR" [%s/%s]\n", cs->name, cs->total, cs->atomic ? "atomic" : (cs->code ? "code" : "pointerful"), cs->uncollectable ? "eternal" : "collectable"); total += cs->total; } - FPRINTF(STDERR, "%12s: %10ld\n", "total", total); + FPRINTF(STDERR, "%12s: %10"PRIdPTR"\n", "total", total); } #endif FPRINTF(STDERR, "End Map\n"); @@ -2651,7 +2653,7 @@ static void *do_malloc(SET_NO_BACKINFO || block->top < block->start || block->top > block->end) FPRINTF(STDERR, - "bad block: %ld %ld %ld %ld\n", + "bad block: %"PRIdPTR" %"PRIdPTR" %"PRIdPTR" %"PRIdPTR"\n", size, block->start, block->top, block->end); #endif @@ -3080,7 +3082,7 @@ static void free_chunk(MemoryChunk *k, MemoryChunk **prev, GC_Set *set) mem_real_use -= (k->end - k->start + sizeof(MemoryChunk)); #if PRINT && 0 - FPRINTF(STDERR, "free chunk: %ld (%ld) %d %d\n", + FPRINTF(STDERR, "free chunk: %"PRIdPTR" (%"PRIdPTR") %d %d\n", (uintptr_t)k, k->end - k->start, set->atomic, set->uncollectable); #endif @@ -3121,7 +3123,7 @@ void GC_free(void *p) if (!found) { # if CHECK_FREES char b[256]; - sprintf(b, "GC_free failed! %lx\n", (intptr_t)p); + sprintf(b, "GC_free failed! %"PRIxPTR"\n", (intptr_t)p); free_error(b); # endif return; @@ -3138,13 +3140,13 @@ void GC_free(void *p) # if CHECK_FREES if (block->free[pos] & fbit) { char b[256]; - sprintf(b, "Block element already free! %lx\n", (intptr_t)p); + sprintf(b, "Block element already free! %"PRIxPTR"\n", (intptr_t)p); return; } # if EXTRA_FREE_CHECKS if (block->set_no != 5) { char b[256]; - sprintf(b, "GC_free on ptr from wrong block! %lx\n", (intptr_t)p); + sprintf(b, "GC_free on ptr from wrong block! %"PRIxPTR"\n", (intptr_t)p); free_error(b); return; } @@ -3196,7 +3198,7 @@ void GC_free(void *p) # if CHECK_FREES && EXTRA_FREE_CHECKS if (chunk->set_no != 5) { char b[256]; - sprintf(b, "GC_free on ptr from wrong block! %lx\n", (intptr_t)p); + sprintf(b, "GC_free on ptr from wrong block! %"PRIxPTR"\n", (intptr_t)p); free_error(b); return; } @@ -3210,7 +3212,7 @@ void GC_free(void *p) # if CHECK_FREES else { char b[256]; - sprintf(b, "GC_free on block interior! %lx != %lx\n", + sprintf(b, "GC_free on block interior! %"PRIxPTR" != %"PRIxPTR"\n", (intptr_t)p, (intptr_t)PAD_FORWARD(found)); free_error(b); } @@ -3247,7 +3249,7 @@ static void bad_pad(char *where, void *s, int type, intptr_t sz, intptr_t diff, intptr_t pd, intptr_t expect) { FPRINTF(STDERR, - "pad %s violation at %lx <%d>, len %ld (diff %ld+%ld): %lx != %lx\n", + "pad %s violation at %"PRIxPTR" <%d>, len %"PRIdPTR" (diff %"PRIdPTR"+%"PRIdPTR"): %"PRIxPTR" != %"PRIxPTR"\n", where, (uintptr_t)s, type, sz, diff, offset, pd, expect); } #endif @@ -3470,7 +3472,7 @@ static void collect_finish_common(BlockOfMemory **blocks, || block->top < block->start || block->top > block->end) FPRINTF(STDERR, - "bad block: %ld %ld %ld %ld\n", + "bad block: %"PRIdPTR" %"PRIdPTR" %"PRIdPTR" %"PRIdPTR"\n", size, block->start, block->top, block->end); #endif @@ -3785,7 +3787,7 @@ static void push_stack(void *stack_now) end = PTR_TO_INT(stack_now); #if PRINT && STAMP_AND_REMEMBER_SOURCE - FPRINTF(STDERR, "stack in [%lx, %lx]\n", start, end); + FPRINTF(STDERR, "stack in [%"PRIxPTR", %"PRIxPTR"]\n", start, end); #endif if (start < end) { @@ -3813,7 +3815,7 @@ static void push_stack(void *stack_now) prepare_stack_collect(); #if PRINT && STAMP_AND_REMEMBER_SOURCE - FPRINTF(STDERR, "jmpbuf in [%lx, %lx]\n", start, end); + FPRINTF(STDERR, "jmpbuf in [%"PRIxPTR", %"PRIxPTR"]\n", start, end); #endif } @@ -4082,7 +4084,7 @@ static void mark_common_for_finalizations(BlockOfMemory **blocks, int atomic) #if WATCH_FOR_FINALIZATION_CYCLES collect(); if (IS_MARKED(block->free[apos] & bit)) - FPRINTF(STDERR, "cycle: %lx\n", p); + FPRINTF(STDERR, "cycle: %"PRIxPTR"\n", p); #endif } } @@ -4482,7 +4484,7 @@ static void do_GC_gcollect(void *stack_now) intptr_t orig_mem_use = mem_use; intptr_t start_time; start_time = GETTIME(); - FPRINTF(STDERR, "gc at %ld (%ld): %ld after %ld msecs\n", + FPRINTF(STDERR, "gc at %"PRIdPTR" (%"PRIdPTR"): %"PRIdPTR" after %"PRIdPTR" msecs\n", mem_use, sector_mem_use, # if GET_MEM_VIA_SBRK (intptr_t)sbrk(0), @@ -4528,7 +4530,7 @@ static void do_GC_gcollect(void *stack_now) # endif INITTIME(); - PRINTTIME((STDERR, "gc: init start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: init start: %"PRIdPTR"\n", GETTIMEREL())); for (j = 0; j < num_common_sets; j++) { # if ALLOW_SET_LOCKING @@ -4547,18 +4549,18 @@ static void do_GC_gcollect(void *stack_now) # if CHECK if (num_chunks != chk_count) { - FPRINTF(STDERR, "bad chunk count: %ld != %ld\n", num_chunks, chk_count); + FPRINTF(STDERR, "bad chunk count: %"PRIdPTR" != %"PRIdPTR"\n", num_chunks, chk_count); } if (num_blocks != cmn_count) { - FPRINTF(STDERR, "bad block count: %ld != %ld\n", num_blocks, cmn_count); + FPRINTF(STDERR, "bad block count: %"PRIdPTR" != %"PRIdPTR"\n", num_blocks, cmn_count); } # endif # if PRINT - FPRINTF(STDERR, "gc at %ld (%ld)\n", mem_use, mem_real_use); + FPRINTF(STDERR, "gc at %"PRIdPTR" (%"PRIdPTR")\n", mem_use, mem_real_use); FPRINTF(STDERR, - "low: %lx hi: %lx blocks: %ld chunks: %ld\n", + "low: %"PRIxPTR" hi: %"PRIxPTR" blocks: %"PRIdPTR" chunks: %"PRIdPTR"\n", low_plausible, high_plausible, num_blocks, num_chunks); # endif @@ -4609,7 +4611,7 @@ static void do_GC_gcollect(void *stack_now) # endif } - PRINTTIME((STDERR, "gc: root collect start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: root collect start: %"PRIdPTR"\n", GETTIMEREL())); # if ALLOW_TRACE_COUNT collect_trace_count = 0; @@ -4643,20 +4645,20 @@ static void do_GC_gcollect(void *stack_now) root_marked = mem_use; # endif - PRINTTIME((STDERR, "gc: stack push start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: stack push start: %"PRIdPTR"\n", GETTIMEREL())); /*** Mark from stack ***/ push_stack(stack_now); # if PRINT && 0 - FPRINTF(STDERR, "stack until: %ld\n", collect_end_stackbased); + FPRINTF(STDERR, "stack until: %"PRIdPTR"\n", collect_end_stackbased); # endif # if ALLOW_TRACE_PATH current_trace_source = "stack"; # endif - PRINTTIME((STDERR, "gc: stack collect start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: stack collect start: %"PRIdPTR"\n", GETTIMEREL())); collect(); @@ -4665,7 +4667,7 @@ static void do_GC_gcollect(void *stack_now) collect_trace_count = 0; # endif - PRINTTIME((STDERR, "gc: uncollectable start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: uncollectable start: %"PRIdPTR"\n", GETTIMEREL())); /*** Uncollectable and pointerful ***/ for (j = 0; j < num_common_sets; j++) @@ -4696,10 +4698,10 @@ static void do_GC_gcollect(void *stack_now) # endif if (GC_push_last_roots) { - PRINTTIME((STDERR, "gc: last roots push start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: last roots push start: %"PRIdPTR"\n", GETTIMEREL())); /*** ``Last'' roots external hook ***/ GC_push_last_roots(); - PRINTTIME((STDERR, "gc: last roots start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: last roots start: %"PRIdPTR"\n", GETTIMEREL())); } # if ALLOW_TRACE_PATH @@ -4714,7 +4716,7 @@ static void do_GC_gcollect(void *stack_now) collect_trace_count = 0; # endif - PRINTTIME((STDERR, "gc: queue finalize start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: queue finalize start: %"PRIdPTR"\n", GETTIMEREL())); # if ALLOW_TRACE_PATH current_trace_source = "finalization"; @@ -4727,7 +4729,7 @@ static void do_GC_gcollect(void *stack_now) traced_from_finals = collect_trace_count; # endif - PRINTTIME((STDERR, "gc: finish start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: finish start: %"PRIdPTR"\n", GETTIMEREL())); low_plausible = high_plausible = 0; @@ -4743,11 +4745,11 @@ static void do_GC_gcollect(void *stack_now) flush_freed_sectors(); #endif - PRINTTIME((STDERR, "gc: all done: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: all done: %"PRIdPTR"\n", GETTIMEREL())); # if PRINT FPRINTF(STDERR, - "done %ld (%ld), %ld from stack\n", mem_use, mem_real_use, + "done %"PRIdPTR" (%"PRIdPTR"), %"PRIdPTR" from stack\n", mem_use, mem_real_use, mem_use - root_marked); # endif @@ -4782,7 +4784,7 @@ static void do_GC_gcollect(void *stack_now) #endif #if PRINT_INFO_PER_GC - FPRINTF(STDERR, "done %ld (%ld); recovered %ld in %ld msecs\n", + FPRINTF(STDERR, "done %"PRIdPTR" (%"PRIdPTR"); recovered %"PRIdPTR" in %"PRIdPTR" msecs\n", mem_use, sector_mem_use, orig_mem_use - mem_use, (intptr_t)GETTIME() - start_time); # if SHOW_SECTOR_MAPS_AT_GC @@ -4803,9 +4805,9 @@ static void do_GC_gcollect(void *stack_now) GC_collect_end_callback(); /* Run queued finalizers. Garbage collections may happen: */ - PRINTTIME((STDERR, "gc: finalize start: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: finalize start: %"PRIdPTR"\n", GETTIMEREL())); run_finalizers(); - PRINTTIME((STDERR, "gc: finalize end: %ld\n", GETTIMEREL())); + PRINTTIME((STDERR, "gc: finalize end: %"PRIdPTR"\n", GETTIMEREL())); #if MARK_STATS fprintf(STDERR, diff --git a/racket/src/racket/src/Makefile.in b/racket/src/racket/src/Makefile.in index 22d8ba1319..e47890dfb0 100644 --- a/racket/src/racket/src/Makefile.in +++ b/racket/src/racket/src/Makefile.in @@ -303,7 +303,7 @@ SCONFIG = $(srcdir)/../sconfig.h $(srcdir)/../uconfig.h ../mzconfig.h COMMON_HEADERS = $(srcdir)/schpriv.h $(srcdir)/schexn.h $(SCONFIG) $(srcdir)/../include/scheme.h \ $(srcdir)/../include/schthread.h $(srcdir)/mzrt.h $(srcdir)/mzrt_cas.inc \ - $(srcdir)/longdouble/longdouble.h + $(srcdir)/longdouble/longdouble.h $(srcdir)/../utils/schiptr.h JIT_HEADERS = $(srcdir)/jit.h $(srcdir)/jitfpu.h $(srcdir)/stypes.h \ $(srcdir)/lightning/i386/core.h $(srcdir)/lightning/i386/core-common.h \ $(srcdir)/lightning/i386/asm.h $(srcdir)/lightning/i386/asm-common.h \ diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 33846fcf59..e4effeefaa 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2536,13 +2536,7 @@ Scheme_Object *scheme_load_delayed_code(int pos, struct Scheme_Load_Delay *ld); intptr_t scheme_get_print_width(void); -#ifndef PRIdPTR -# ifndef PRINTF_INTPTR_SIZE_PREFIX -# define PRINTF_INTPTR_SIZE_PREFIX "l" -# endif -# define PRIdPTR PRINTF_INTPTR_SIZE_PREFIX "d" -# define PRIxPTR PRINTF_INTPTR_SIZE_PREFIX "x" -#endif +#include "../utils/schiptr.h" /*========================================================================*/ /* compile and link */ diff --git a/racket/src/racket/utils/schiptr.h b/racket/src/racket/utils/schiptr.h new file mode 100644 index 0000000000..11cd9fb830 --- /dev/null +++ b/racket/src/racket/utils/schiptr.h @@ -0,0 +1,8 @@ + +#ifndef PRIdPTR +# ifndef PRINTF_INTPTR_SIZE_PREFIX +# define PRINTF_INTPTR_SIZE_PREFIX "l" +# endif +# define PRIdPTR PRINTF_INTPTR_SIZE_PREFIX "d" +# define PRIxPTR PRINTF_INTPTR_SIZE_PREFIX "x" +#endif From 59300afbef7d359b271b1ff2f2cae92d4d78c9c5 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 11 Aug 2015 19:32:29 -0400 Subject: [PATCH 032/381] add racket/private/custom-write --- .../collects/racket/private/custom-write.rkt | 75 +++++++++++++++++++ racket/collects/unstable/custom-write.rkt | 71 ------------------ 2 files changed, 75 insertions(+), 71 deletions(-) create mode 100644 racket/collects/racket/private/custom-write.rkt diff --git a/racket/collects/racket/private/custom-write.rkt b/racket/collects/racket/private/custom-write.rkt new file mode 100644 index 0000000000..83b9a9eaa1 --- /dev/null +++ b/racket/collects/racket/private/custom-write.rkt @@ -0,0 +1,75 @@ +#lang racket/base +(require racket/pretty) +(provide make-constructor-style-printer) + +;; make-constructor-style-printer : (Any -> (U String Symbol)) +;; (Any -> (Sequenceof Any)) +;; -> (Any OutputPort (U #t #f 0 1)) -> Void +(define (make-constructor-style-printer get-constructor get-contents) + (lambda (obj port mode) + (define (recur x p) + (case mode + ((#t) (write x p)) + ((#f) (display x p)) + ((0 1) (print x p mode)))) + + ;; Only two cases: 0 vs everything else + (define (print-prefix p) + (let ([prefix + (case mode + ((0) "(") + (else "#<"))] + [constructor + (get-constructor obj)] + [post-constr + (case mode + ((0) "") + (else ":"))]) + (write-string prefix p) + (display constructor p) + (write-string post-constr p))) + + (define (print-suffix p) + (let ([suffix + (case mode + ((0) ")") + (else ">"))]) + (write-string suffix p))) + + (define (print-contents p leading-space) + (let ([lead (if leading-space (make-string (add1 leading-space) #\space) " ")]) + (for ([elt (get-contents obj)]) ;; note: generic sequence + (when leading-space + (pretty-print-newline p (pretty-print-columns))) + (write-string lead p) + (recur elt p)))) + + (define (print/one-line p) + (print-prefix p) + (print-contents p #f) + (print-suffix p)) + + (define (print/multi-line p) + (let-values ([(line col pos) (port-next-location p)]) + (print-prefix p) + (print-contents p col) + (print-suffix p))) + + (cond [(and (pretty-printing) + (integer? (pretty-print-columns))) + ((let/ec esc + (letrec ([tport + (make-tentative-pretty-print-output-port + port + (- (pretty-print-columns) 1) + (lambda () + (esc + (lambda () + (tentative-pretty-print-port-cancel tport) + (print/multi-line port)))))]) + (print/one-line tport) + (tentative-pretty-print-port-transfer tport port)) + void))] + [else + (print/one-line port)]) + (void))) diff --git a/racket/collects/unstable/custom-write.rkt b/racket/collects/unstable/custom-write.rkt index 761d0a3d29..fb85bfb655 100644 --- a/racket/collects/unstable/custom-write.rkt +++ b/racket/collects/unstable/custom-write.rkt @@ -70,74 +70,3 @@ Constructor-style printer (sequence-append (get-super-contents obj) (get-new-contents obj))) get-new-contents)))])) - -;; ---- - -(define (make-constructor-style-printer get-constructor get-contents) - (lambda (obj port mode) - (define (recur x p) - (case mode - ((#t) (write x p)) - ((#f) (display x p)) - ((0 1) (print x p mode)))) - - ;; Only two cases: 0 vs everything else - (define (print-prefix p) - (let ([prefix - (case mode - ((0) "(") - (else "#<"))] - [constructor - (get-constructor obj)] - [post-constr - (case mode - ((0) "") - (else ":"))]) - (write-string prefix p) - (display constructor p) - (write-string post-constr p))) - - (define (print-suffix p) - (let ([suffix - (case mode - ((0) ")") - (else ">"))]) - (write-string suffix p))) - - (define (print-contents p leading-space) - (let ([lead (if leading-space (make-string (add1 leading-space) #\space) " ")]) - (for ([elt (get-contents obj)]) - (when leading-space - (pretty-print-newline p (pretty-print-columns))) - (write-string lead p) - (recur elt p)))) - - (define (print/one-line p) - (print-prefix p) - (print-contents p #f) - (print-suffix p)) - - (define (print/multi-line p) - (let-values ([(line col pos) (port-next-location p)]) - (print-prefix p) - (print-contents p col) - (print-suffix p))) - - (cond [(and (pretty-printing) - (integer? (pretty-print-columns))) - ((let/ec esc - (letrec ([tport - (make-tentative-pretty-print-output-port - port - (- (pretty-print-columns) 1) - (lambda () - (esc - (lambda () - (tentative-pretty-print-port-cancel tport) - (print/multi-line port)))))]) - (print/one-line tport) - (tentative-pretty-print-port-transfer tport port)) - void))] - [else - (print/one-line port)]) - (void))) From 0f6e2f802979ae9d2ec5714e90422b50ab19eb9b Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 11 Aug 2015 20:02:35 -0400 Subject: [PATCH 033/381] change sets to use make-constructor-style-printer --- racket/collects/racket/private/set-types.rkt | 98 ++++++-------------- 1 file changed, 26 insertions(+), 72 deletions(-) diff --git a/racket/collects/racket/private/set-types.rkt b/racket/collects/racket/private/set-types.rkt index 53c19fd8cf..dbb587617f 100644 --- a/racket/collects/racket/private/set-types.rkt +++ b/racket/collects/racket/private/set-types.rkt @@ -1,5 +1,6 @@ #lang racket/base (require racket/private/set + racket/private/custom-write racket/stream racket/serialize racket/pretty @@ -354,79 +355,32 @@ [(hash-eq? x) (hash-eq? y)])) (define (write-custom-set s port mode) + (cond [(custom-set-spec s) + (define table (custom-set-table s)) + (define key-str + (cond [(immutable? table) ""] + [(hash-weak? table) "weak-"] + [else "mutable-"])) + (fprintf port "#<~acustom-set>" key-str)] + [else (write-hash-set s port mode)])) - (define table (custom-set-table s)) - (define key-str - (cond - [(immutable? table) ""] - [(hash-weak? table) "weak-"] - [else "mutable-"])) - - (cond - [(custom-set-spec s) (fprintf port "#<~acustom-set>" key-str)] - [else - - (define show - (case mode - [(#t) write] - [(#f) display] - [else (lambda (p port) (print p port mode))])) - - (define-values (left-str mid-str right-str) - (case mode - [(0) (values "(" "" ")")] - [else (values "#<" ":" ">")])) - (define cmp-str - (cond - [(hash-equal? table) "set"] - [(hash-eqv? table) "seteqv"] - [(hash-eq? table) "seteq"])) - - (define (show-prefix port) - (write-string left-str port) - (write-string key-str port) - (write-string cmp-str port) - (write-string mid-str port)) - - (define (show-suffix port) - (write-string right-str port)) - - (define (show-one-line port) - (show-prefix port) - (for ([k (in-hash-keys table)]) - (write-string " " port) - (show k port)) - (show-suffix port)) - - (define (show-multi-line port) - (define-values (line col pos) (port-next-location port)) - (show-prefix port) - (for ([k (in-hash-keys table)]) - (pretty-print-newline port (pretty-print-columns)) - (for ([i (in-range (add1 col))]) - (write-char #\space port)) - (show k port)) - (show-suffix port)) - - (cond - [(and (pretty-printing) - (integer? (pretty-print-columns))) - (define proc - (let/ec return - (define pretty-port - (make-tentative-pretty-print-output-port - port - (- (pretty-print-columns) 1) - (lambda () - (return - (lambda () - (tentative-pretty-print-port-cancel pretty-port) - (show-multi-line port)))))) - (show-one-line port) - (tentative-pretty-print-port-transfer pretty-port port) - void)) - (proc)] - [else (show-one-line port)])])) +(define write-hash-set + (make-constructor-style-printer + (lambda (s) + (define table (custom-set-table s)) + (define key-str + (cond [(immutable? table) ""] + [(hash-weak? table) "weak-"] + [else "mutable-"])) + (cond [(custom-set-spec s) + (string-append key-str "custom-set")] + [else + (define cmp-str + (cond [(hash-equal? table) "set"] + [(hash-eqv? table) "seteqv"] + [(hash-eq? table) "seteq"])) + (string-append key-str cmp-str)])) + (lambda (s) (hash-keys (custom-set-table s))))) (define (custom-in-set s) (define keys (in-hash-keys (custom-set-table s))) From aee93fb20042f7f1cdaf4a8009cad227a74f6a95 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Wed, 12 Aug 2015 17:39:24 -0400 Subject: [PATCH 034/381] added racket/struct with make-constructor-style-printer --- racket/collects/racket/struct.rkt | 8 ++++++++ racket/collects/unstable/custom-write.rkt | 10 ++++------ 2 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 racket/collects/racket/struct.rkt diff --git a/racket/collects/racket/struct.rkt b/racket/collects/racket/struct.rkt new file mode 100644 index 0000000000..765e6bca5e --- /dev/null +++ b/racket/collects/racket/struct.rkt @@ -0,0 +1,8 @@ +#lang racket/base +(require "private/custom-write.rkt" + racket/contract/base) +(provide (contract-out + [make-constructor-style-printer + (-> (-> any/c (or/c symbol? string?)) + (-> any/c sequence?) + (-> any/c output-port? (or/c #t #f 0 1) void?))])) diff --git a/racket/collects/unstable/custom-write.rkt b/racket/collects/unstable/custom-write.rkt index fb85bfb655..de68d943f9 100644 --- a/racket/collects/unstable/custom-write.rkt +++ b/racket/collects/unstable/custom-write.rkt @@ -1,13 +1,11 @@ #lang racket/base -(require racket/pretty +(require racket/struct + racket/pretty racket/match racket/sequence racket/contract/base) -(provide (contract-out - [make-constructor-style-printer - (-> (-> any/c (or/c symbol? string?)) - (-> any/c sequence?) - (-> any/c output-port? (or/c #t #f 0 1) void?))] +(provide make-constructor-style-printer + (contract-out [prop:auto-custom-write (struct-type-property/c 'constructor)])) From 86ee9c50716f5c5209104a80b9d7b015f2f800b2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 10:10:41 -0600 Subject: [PATCH 035/381] signature-members: adjust element ids based on reference Make the resulting content ids compatible with binding and reference at a use site, as needed for the new macro expander. --- .../scribblings/reference/units.scrbl | 4 +++ pkgs/racket-test/tests/units/test-exptime.rkt | 36 +++++++++++++++++++ racket/collects/racket/unit-exptime.rkt | 12 ++++--- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/units.scrbl b/pkgs/racket-doc/scribblings/reference/units.scrbl index 6f8da3ee96..8416733e4e 100644 --- a/pkgs/racket-doc/scribblings/reference/units.scrbl +++ b/pkgs/racket-doc/scribblings/reference/units.scrbl @@ -876,6 +876,10 @@ values: ] +Each of the result identifiers is given a lexical context that is +based on @racket[sig-identifier], so the names are suitable for +reference or binding in the context of @racket[sign-identifier]. + If @racket[sig-identifier] is not bound to a signature, then the @exnraise[exn:fail:syntax]. In that case, the given @racket[err-syntax] argument is used as the source of the error, where diff --git a/pkgs/racket-test/tests/units/test-exptime.rkt b/pkgs/racket-test/tests/units/test-exptime.rkt index db732446ac..98c6087f58 100644 --- a/pkgs/racket-test/tests/units/test-exptime.rkt +++ b/pkgs/racket-test/tests/units/test-exptime.rkt @@ -52,4 +52,40 @@ (test '((#f . one^)) (unit-dep-info one@ quote)) (test '((Four . four^)) (unit-dep-info two@ quote)) +(module m racket/base + (require racket/unit + (for-syntax racket/base)) + (provide x^ y^) + (define-signature x^ (x)) + (define-signature y^ (y + (define-syntaxes (get-y) (lambda (stx) #'y)) + (define-values (y2) 10)))) +(require 'm) + +;; based on code by Jay: +(define-syntax (as-s stx) + (syntax-case stx () + [(_ e ...) + (with-syntax ([([i-export e-export] ...) + (let-values ([(_1 ids _2 _3) (signature-members #'x^ stx)]) + (for/list ([i (in-list ids)]) + (list i (datum->syntax stx (syntax->datum i)))))] + [([i-import e-import] ...) + (let-values ([(_1 ids var-ids stx-ids) (signature-members #'y^ stx)]) + (for/list ([i (in-list (append ids var-ids stx-ids))]) + (list i (datum->syntax stx (syntax->datum i)))))]) + (syntax/loc stx + (unit (import y^) (export x^) + (define-syntax e-import (make-rename-transformer #'i-import)) + ... + e ... + (define i-export e-export) + ...)))])) +(define y 'y) +(define-values/invoke-unit + (as-s (define x (list y (get-y) y2))) + (import y^) + (export x^)) +(test '(y y 10) x) + (displayln "tests passed") diff --git a/racket/collects/racket/unit-exptime.rkt b/racket/collects/racket/unit-exptime.rkt index e86cf9a89c..7cd1b67b4e 100644 --- a/racket/collects/racket/unit-exptime.rkt +++ b/racket/collects/racket/unit-exptime.rkt @@ -21,13 +21,17 @@ (define (signature-members name err-stx) (parameterize ((error-syntax err-stx)) (let ([s (lookup-signature name)]) + (define intro + (make-relative-introducer name + (car (siginfo-names (signature-siginfo s))))) (values ;; extends: (and (pair? (cdr (siginfo-names (signature-siginfo s)))) - (cadr (siginfo-names (signature-siginfo s)))) + (intro (cadr (siginfo-names (signature-siginfo s))))) ;; vars - (apply list (signature-vars s)) + (map intro + (apply list (signature-vars s))) ;; defined vars - (apply list (apply append (map car (signature-val-defs s)))) + (map intro (apply list (apply append (map car (signature-val-defs s))))) ;; defined stxs - (apply list (apply append (map car (signature-stx-defs s)))))))) + (map intro (apply list (apply append (map car (signature-stx-defs s))))))))) From 7741b4b361894d6096c1afe08f2726f2fb0eb629 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 11:45:00 -0600 Subject: [PATCH 036/381] local-expand: fix argument checking Also, fix contract in the docs, since the first argument is allowed to be an S-expression. --- .../scribblings/reference/stx-trans.scrbl | 14 ++++++++------ pkgs/racket-test-core/tests/racket/macro.rktl | 17 +++++++++++++++++ racket/src/racket/src/eval.c | 6 ++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index 7203dc28da..8b87be0dd3 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -197,7 +197,7 @@ field value is not an identifier, then an identifier @racketidfont{?} with an empty context is used, instead.} -@defproc[(local-expand [stx syntax?] +@defproc[(local-expand [stx any/c] [context-v (or/c 'expression 'top-level 'module 'module-begin list?)] [stop-ids (or/c (listof identifier?) #f)] [intdef-ctx (or/c internal-definition-context? @@ -211,7 +211,9 @@ Expands @racket[stx] in the lexical context of the expression currently being expanded. The @racket[context-v] argument is used as the result of @racket[syntax-local-context] for immediate expansions; a list indicates an @tech{internal-definition context}, and more -information on the form of the list is below. +information on the form of the list is below. If @racket[stx] is not +already a @tech{syntax object}, it is coerced with +@racket[(datum->syntax #f stx)] before expansion. When an identifier in @racket[stop-ids] is encountered by the expander in a sub-expression, expansions stops for the sub-expression. If @@ -297,7 +299,7 @@ generated value onto that list. an explicit wrapper.}]} -@defproc[(syntax-local-expand-expression [stx syntax?]) +@defproc[(syntax-local-expand-expression [stx any/c]) (values syntax? syntax?)]{ Like @racket[local-expand] given @racket['expression] and an empty @@ -316,7 +318,7 @@ avoids quadratic expansion times when local expansions are nested. @transform-time[]} -@defproc[(local-transformer-expand [stx syntax?] +@defproc[(local-transformer-expand [stx any/c] [context-v (or/c 'expression 'top-level list?)] [stop-ids (or/c (listof identifier?) #f)] [intdef-ctx (or/c internal-definition-context? #f) #f]) @@ -331,7 +333,7 @@ lifted expressions---from calls to result.} -@defproc[(local-expand/capture-lifts [stx syntax?] +@defproc[(local-expand/capture-lifts [stx any/c] [context-v (or/c 'expression 'top-level 'module 'module-begin list?)] [stop-ids (or/c (listof identifier?) #f)] [intdef-ctx (or/c internal-definition-context? #f) #f] @@ -349,7 +351,7 @@ expressions are not expanded, but instead left as provided in the @racket[begin] form.} -@defproc[(local-transformer-expand/capture-lifts [stx syntax?] +@defproc[(local-transformer-expand/capture-lifts [stx any/c] [context-v (or/c 'expression 'top-level list?)] [stop-ids (or/c (listof identifier?) #f)] [intdef-ctx (or/c internal-definition-context? #f) #f] diff --git a/pkgs/racket-test-core/tests/racket/macro.rktl b/pkgs/racket-test-core/tests/racket/macro.rktl index 2d570f7311..44a373b56e 100644 --- a/pkgs/racket-test-core/tests/racket/macro.rktl +++ b/pkgs/racket-test-core/tests/racket/macro.rktl @@ -1258,6 +1258,23 @@ (def) (use))) +;; ---------------------------------------- +;; Check `local-expand` argument checking + +(let-syntax ([m + (lambda (stx) + (define (le . args) + (with-handlers ([exn:fail:contract? void]) + (apply local-expand args) + (error "fail"))) + (le #'1 'xpression null) + (le #'1 'expression 1) + (le #'1 'expression #'1) + (le #'1 'expression #'(x)) + (le #'1 'expression (list 'x)) + #'#t)]) + (void (m))) + ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 0501a02a04..f5d6c3a616 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -5160,9 +5160,11 @@ do_local_expand(const char *name, int for_stx, int catch_lifts, int for_expr, in if (for_expr) { } else if (SCHEME_TRUEP(argv[2])) { # define NUM_CORE_EXPR_STOP_FORMS 15 - cnt = scheme_stx_proper_list_length(argv[2]); + cnt = scheme_proper_list_length(argv[2]); - if (cnt == 1) + if ((cnt == 1) + && SCHEME_STXP(SCHEME_CAR(argv[2])) + && SCHEME_SYMBOLP(SCHEME_STX_VAL(SCHEME_CAR(argv[2])))) is_modstar = scheme_stx_free_eq_x(scheme_modulestar_stx, SCHEME_CAR(argv[2]), env->genv->phase); else is_modstar = 0; From 7d6bec2b176e8ac2fa0eb9b45886155d4ddaa49e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 11:51:23 -0600 Subject: [PATCH 037/381] increase timeout for "determistic-zo.rkt" test --- pkgs/racket-test/tests/racket/deterministic-zo.rkt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/racket-test/tests/racket/deterministic-zo.rkt b/pkgs/racket-test/tests/racket/deterministic-zo.rkt index 5b8762aa6b..b0544100ad 100644 --- a/pkgs/racket-test/tests/racket/deterministic-zo.rkt +++ b/pkgs/racket-test/tests/racket/deterministic-zo.rkt @@ -66,3 +66,7 @@ #; (check-one collects-dir "syntax" "free-vars.rkt") (check (simplify-path collects-dir)) (void)) + +(module+ test + (module config info + (define timeout 300))) From bd82646d81f96c1a43719ea143819917d3256ba0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 11:55:44 -0600 Subject: [PATCH 038/381] avoid compiler warnings --- racket/src/racket/src/resolve.c | 9 +-------- racket/src/racket/src/sfs.c | 3 +-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 37d88ff98c..d5d947cc84 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -3612,7 +3612,6 @@ static Scheme_Object *unresolve_let_void(Scheme_Object *e, Unresolve_Info *ui) { int i, pos, count, *flags; Scheme_Let_Header *lh; Scheme_Object *o; - Scheme_Compiled_Let_Value **clvmap; Unresolve_Let_Void_State *state; state = scheme_malloc(sizeof(Unresolve_Let_Void_State)); @@ -3620,7 +3619,6 @@ static Scheme_Object *unresolve_let_void(Scheme_Object *e, Unresolve_Info *ui) { count = lv->count; pos = unresolve_stack_push(ui, count, 0, 0); lh = make_let_header(count); - clvmap = MALLOC_N(Scheme_Compiled_Let_Value*, count); o = lv->body; attach_lv(lh, NULL, NULL, NULL, state); @@ -3734,7 +3732,6 @@ static Scheme_Object *unresolve_prefix_symbol(Scheme_Object *s, Unresolve_Info * static Scheme_Object *unresolve_closure(Scheme_Object *e, Unresolve_Info *ui) { Scheme_Object *r, *c; - int stack_pos, depth; c = scheme_hash_get(ui->closures, e); @@ -3742,9 +3739,6 @@ static Scheme_Object *unresolve_closure(Scheme_Object *e, Unresolve_Info *ui) { return c; } - stack_pos = ui->stack_pos; - depth = ui->depth; - r = unresolve_closure_data_2(SCHEME_COMPILED_CLOS_CODE(e), ui); return r; } @@ -4395,7 +4389,7 @@ static Scheme_Object *unresolve_expr_2(Scheme_Object *e, Unresolve_Info *ui, int { Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)e, *wcm2; Scheme_Object *k, *v, *b; - int *flags, pos; + int pos; k = unresolve_expr_2(wcm->key, ui, 0); if (!k) return_NULL; @@ -4405,7 +4399,6 @@ static Scheme_Object *unresolve_expr_2(Scheme_Object *e, Unresolve_Info *ui, int pos = unresolve_stack_push(ui, 1, 0, 0); b = unresolve_expr_2(wcm->body, ui, 0); if (!b) return_NULL; - flags = unresolve_stack_pop(ui, pos, 1); wcm2 = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); wcm2->so.type = scheme_with_immed_mark_type; diff --git a/racket/src/racket/src/sfs.c b/racket/src/racket/src/sfs.c index 3f551f4b1a..99daeace50 100644 --- a/racket/src/racket/src/sfs.c +++ b/racket/src/racket/src/sfs.c @@ -909,7 +909,7 @@ static Scheme_Object *with_immed_mark_sfs(Scheme_Object *o, SFS_Info *info) { Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)o; Scheme_Object *k, *v, *b, *vec; - int pos, save_mnt, ip; + int pos, save_mnt; scheme_sfs_start_sequence(info, 3, 1); @@ -918,7 +918,6 @@ static Scheme_Object *with_immed_mark_sfs(Scheme_Object *o, SFS_Info *info) scheme_sfs_push(info, 1, 1); - ip = info->ip; pos = info->stackpos; save_mnt = info->max_nontail; From 2d23ca1414508757aa7afb1bcae5bb6951e492f9 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 13:32:57 -0500 Subject: [PATCH 039/381] Make doc section title more accurate. --- pkgs/racket-doc/scribblings/reference/sequences.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index 57929f97e8..09110f4688 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -614,7 +614,7 @@ each element in the sequence. values in the sequence), the @exnraise[exn:fail:contract].} @; ---------------------------------------------------------------------- -@subsection[#:tag "more-sequences"]{Sequence Combinations & Contract} +@subsection[#:tag "more-sequences"]{Additional Sequence Operations} @note-lib[racket/sequence] From 1a7b71fb205886fd602e5366413096360e29e4e2 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 14:47:43 -0500 Subject: [PATCH 040/381] Improve the implementation of `in-slice`. --- racket/collects/unstable/sequence.rkt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/racket/collects/unstable/sequence.rkt b/racket/collects/unstable/sequence.rkt index f2b6b1b4fb..afbe55d8c8 100644 --- a/racket/collects/unstable/sequence.rkt +++ b/racket/collects/unstable/sequence.rkt @@ -62,22 +62,18 @@ ;; Added by stamourv (from David Vanderson (david.vanderson at gmail.com)): (provide/contract - [in-slice (exact-positive-integer? any/c . -> . any)]) + [in-slice (exact-positive-integer? sequence? . -> . any)]) (define (in-slice k seq) - ;; ELI: what's the point of using `any/c' above and then checking it here? - (unless (sequence? seq) (raise-type-error 'in-slice "sequence" seq)) (make-do-sequence (λ () (define-values (more? get) (sequence-generate seq)) (values (λ (_) - ;; ELI: Add an `in-range' - (for/list ([i k] #:when (more?)) + (for/list ([i (in-range k)] #:when (more?)) (get))) values #f #f - ;; ELI: Use `pair?' - (λ (val) (0 . < . (length val))) + (λ (val) (pair? val)) #f)))) From 36bb0e568c19f1f6b7605677fe639b7a9090bb9f Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 14:57:11 -0500 Subject: [PATCH 041/381] Merge part of unstable/syntax with racket/syntax. --- racket/collects/racket/match/define-forms.rkt | 2 +- racket/collects/racket/sequence.rkt | 48 ++++++++++++++++- racket/collects/unstable/sequence.rkt | 52 +------------------ 3 files changed, 49 insertions(+), 53 deletions(-) diff --git a/racket/collects/racket/match/define-forms.rkt b/racket/collects/racket/match/define-forms.rkt index d5cf2497d1..2189982368 100644 --- a/racket/collects/racket/match/define-forms.rkt +++ b/racket/collects/racket/match/define-forms.rkt @@ -3,7 +3,7 @@ (require (for-syntax racket/base racket/syntax (only-in racket/list append* remove-duplicates) - unstable/sequence + racket/sequence syntax/parse/pre syntax/parse/experimental/template racket/lazy-require diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index 5aa738d81e..1910365be2 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -3,7 +3,9 @@ (require "stream.rkt" "private/sequence.rkt" racket/contract/combinator - racket/contract/base) + racket/contract/base + (for-syntax racket/base) + syntax/stx) (provide empty-sequence sequence->list @@ -19,7 +21,10 @@ sequence-filter sequence-add-between sequence-count - sequence/c) + sequence/c + in-syntax + in-pairs + (contract-out [in-slice (exact-positive-integer? sequence? . -> . any)])) (define empty-sequence (make-do-sequence @@ -239,3 +244,42 @@ [(list? seq) (sequence->list result-seq)] [(stream? seq) (sequence->stream result-seq)] [else result-seq]))))) + + +;; additional sequence constructors + +(define-sequence-syntax in-syntax + (λ () #'in-syntax/proc) + (λ (stx) + (syntax-case stx () + [[(id) (_ arg)] + #'[(id) (in-list (in-syntax/proc arg))]]))) + +(define (in-syntax/proc stx) + (or (stx->list stx) + (raise-type-error 'in-syntax "stx-list" stx))) + +(define (in-pairs seq) + (make-do-sequence + (λ () + (let-values ([(more? gen) (sequence-generate seq)]) + (values (λ (e) (let ([e (gen)]) (values (car e) (cdr e)))) + (λ (_) #t) + #t + (λ (_) (more?)) + (λ _ #t) + (λ _ #t)))))) + +(define (in-slice k seq) + (make-do-sequence + (λ () + (define-values (more? get) (sequence-generate seq)) + (values + (λ (_) + (for/list ([i (in-range k)] #:when (more?)) + (get))) + values + #f + #f + (λ (val) (pair? val)) + #f)))) diff --git a/racket/collects/unstable/sequence.rkt b/racket/collects/unstable/sequence.rkt index afbe55d8c8..84302a200d 100644 --- a/racket/collects/unstable/sequence.rkt +++ b/racket/collects/unstable/sequence.rkt @@ -1,38 +1,8 @@ #lang racket/base -(require (for-syntax racket/base) racket/contract/base syntax/stx) +(require racket/sequence) ; for re-export -;; Added by samth: - -(provide in-syntax in-pairs in-sequence-forever sequence-lift) - -;; ELI: I don't see a point in this over using `syntax->list' directly. -;; (Eg, the latter is something that can be used when the programmer -;; knows that it's a list, in contrast to this code which will just -;; throw an error.) -(define-sequence-syntax in-syntax - (λ () #'in-syntax/proc) - (λ (stx) - (syntax-case stx () - [[(id) (_ arg)] - #'[(id) (in-list (in-syntax/proc arg))]]))) - -(define (in-syntax/proc stx) - (or (stx->list stx) - (raise-type-error 'in-syntax "stx-list" stx))) - -;; ELI: This is very specific, and indeed there are no uses of it -;; anywhere in the tree other than in TR where it came from. -(define (in-pairs seq) - (make-do-sequence - (λ () - (let-values ([(more? gen) (sequence-generate seq)]) - (values (λ (e) (let ([e (gen)]) (values (car e) (cdr e)))) - (λ (_) #t) - #t - (λ (_) (more?)) - (λ _ #t) - (λ _ #t)))))) +(provide in-syntax in-pairs in-sequence-forever sequence-lift in-slice) ;; ELI: Besides the awful name, this is the same as ;; (in-sequences seq (in-cycle (in-value val))) @@ -59,21 +29,3 @@ (λ _ #t) (λ _ #t)))))) -;; Added by stamourv (from David Vanderson (david.vanderson at gmail.com)): - -(provide/contract - [in-slice (exact-positive-integer? sequence? . -> . any)]) - -(define (in-slice k seq) - (make-do-sequence - (λ () - (define-values (more? get) (sequence-generate seq)) - (values - (λ (_) - (for/list ([i (in-range k)] #:when (more?)) - (get))) - values - #f - #f - (λ (val) (pair? val)) - #f)))) From 9508c251eeb2cdde23a50ca74dfe0ea05b9e8f27 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 15:03:06 -0500 Subject: [PATCH 042/381] Move rest of unstable/sequence to unstable-lib. --- racket/collects/unstable/sequence.rkt | 31 --------------------------- 1 file changed, 31 deletions(-) delete mode 100644 racket/collects/unstable/sequence.rkt diff --git a/racket/collects/unstable/sequence.rkt b/racket/collects/unstable/sequence.rkt deleted file mode 100644 index 84302a200d..0000000000 --- a/racket/collects/unstable/sequence.rkt +++ /dev/null @@ -1,31 +0,0 @@ -#lang racket/base - -(require racket/sequence) ; for re-export - -(provide in-syntax in-pairs in-sequence-forever sequence-lift in-slice) - -;; ELI: Besides the awful name, this is the same as -;; (in-sequences seq (in-cycle (in-value val))) -(define (in-sequence-forever seq val) - (make-do-sequence - (λ () - (let-values ([(more? gen) (sequence-generate seq)]) - (values (λ (e) (if (more?) (gen) val)) - (λ (_) #t) - #t - (λ (_) #t) - (λ _ #t) - (λ _ #t)))))) - -;; ELI: How is this different from `sequence-map'? -(define (sequence-lift f seq) - (make-do-sequence - (λ () - (let-values ([(more? gen) (sequence-generate seq)]) - (values (λ (e) (call-with-values gen f)) - (λ (_) #t) - #t - (λ (_) (more?)) - (λ _ #t) - (λ _ #t)))))) - From f4f75f2740ba8b4e19289127c6030a98e7e069b5 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 15:16:12 -0500 Subject: [PATCH 043/381] Move docs for part of `unstable/sequence` to the `racket/sequence` docs. --- .../scribblings/reference/sequences.scrbl | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index 09110f4688..ba5e9c37a7 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -780,6 +780,32 @@ If @racket[min-count] is a number, the stream is required to have at least that } +@subsubsection{Additional Sequence Constructors} + +@defproc[(in-syntax [stx syntax?]) sequence?]{ +Produces a sequence equivalent to @racket[(syntax->list lst)]. +@speed[in-syntax "syntax"] + +@examples[#:eval sequence-evaluator +(for/list ([x (in-syntax #'(1 2 3))]) + x)]} + +@defproc[(in-pairs [seq sequence?]) sequence?]{ + Produces a sequence equivalent to + @racket[(in-parallel (sequence-lift car seq) (sequence-lift cdr seq))]. +} + +@defproc[(in-slice [length exact-positive-integer?] [seq sequence?]) + sequence?]{ + Returns a sequence where each element is a list with @racket[length] + elements from the given sequence. + + @examples[#:eval sequence-evaluator + (for/list ([e (in-slice 3 (in-range 8))]) e) + ] +} + + @; ====================================================================== @section[#:tag "streams"]{Streams} From 63b1f0f4aaed136c051e47bbb80bf3bfa35dee9e Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 15:32:30 -0500 Subject: [PATCH 044/381] Improve docs for the new bits of `racket/sequence`. --- .../scribblings/reference/sequences.scrbl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index ba5e9c37a7..8cbaa0ff4d 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -783,22 +783,30 @@ If @racket[min-count] is a number, the stream is required to have at least that @subsubsection{Additional Sequence Constructors} @defproc[(in-syntax [stx syntax?]) sequence?]{ -Produces a sequence equivalent to @racket[(syntax->list lst)]. -@speed[in-syntax "syntax"] + Produces a sequence whose elements are the successive subparts of + @racket[stx]. + Equivalent to @racket[(syntax->list lst)]. + @speed[in-syntax "syntax"] @examples[#:eval sequence-evaluator (for/list ([x (in-syntax #'(1 2 3))]) x)]} @defproc[(in-pairs [seq sequence?]) sequence?]{ - Produces a sequence equivalent to + Produces a 2-valued sequence whose pairs of elements are the successive + @racket[car]s and @racket[cdr]s of the elements of @racket[seq]. + Equivalent to @racket[(in-parallel (sequence-lift car seq) (sequence-lift cdr seq))]. + + @examples[#:eval sequence-evaluator + (for/list ([(a b) (in-pairs '((1 . a) (2 . b) (3 . c)))]) b) + ] } @defproc[(in-slice [length exact-positive-integer?] [seq sequence?]) sequence?]{ - Returns a sequence where each element is a list with @racket[length] - elements from the given sequence. + Returns a sequence whose elements are lists with the first @racket[length] + elements of @racket[seq], then the next @racket[length] and so on. @examples[#:eval sequence-evaluator (for/list ([e (in-slice 3 (in-range 8))]) e) From 8b1859b77db0885c0091835a913eb5e59e7b5e55 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 15:47:51 -0500 Subject: [PATCH 045/381] Move tests for the new bits of `racket/sequence` from `unstable/sequence` tests. --- pkgs/racket-test-core/tests/racket/sequence.rktl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/sequence.rktl b/pkgs/racket-test-core/tests/racket/sequence.rktl index e997e82dea..8c689ce1fb 100644 --- a/pkgs/racket-test-core/tests/racket/sequence.rktl +++ b/pkgs/racket-test-core/tests/racket/sequence.rktl @@ -265,6 +265,22 @@ (define-sequence-syntax in-X* (lambda () #'in-X) (lambda (stx) #f)) (test '(1 2 3) 'kw-seq (for/list ([x (in-X* #:x '(1 2 3))]) x)) +;; ---------------------------------------- +;; Additional sequence constructors + +(test '(2 4 6) + values + (for/list ([(x y) (in-pairs '((1 . 1) (2 . 2) (3 . 3)))]) + (+ x y))) +(test #t sequence? (in-slice 1 '())) +(test '() values (for/list ([v (in-slice 1 '())]) v)) +(test '((0 1)) values (for/list ([v (in-slice 3 (in-range 2))]) v)) +(test '((0 1 2) (3 4 5)) + values (for/list ([v (in-slice 3 (in-range 6))]) v)) +(test '((0 1 2) (3 4 5) (6 7)) + values (for/list ([v (in-slice 3 (in-range 8))]) v)) +(err/rt-test (for/list ([x (in-slice 0 (in-range 8))]) x) exn:fail:contract?) + ;; ---------------------------------------- (report-errs) From 1b0350ec0a004ae262aa2d0897e20562aceaed4b Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 7 Aug 2015 15:59:11 -0500 Subject: [PATCH 046/381] Add more tests. --- pkgs/racket-test-core/tests/racket/sequence.rktl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/sequence.rktl b/pkgs/racket-test-core/tests/racket/sequence.rktl index 8c689ce1fb..2e24bd4578 100644 --- a/pkgs/racket-test-core/tests/racket/sequence.rktl +++ b/pkgs/racket-test-core/tests/racket/sequence.rktl @@ -268,6 +268,12 @@ ;; ---------------------------------------- ;; Additional sequence constructors +(test #t sequence? (in-pairs '())) +(test #t sequence? (in-pairs '((1 . 2) (3 . 4)))) +(test '() + values + (for/list ([(x y) (in-pairs '())]) + x)) (test '(2 4 6) values (for/list ([(x y) (in-pairs '((1 . 1) (2 . 2) (3 . 3)))]) From 52425fbb279f1dcbd04bfcfbef95b9c9e0894ae2 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 9 Aug 2015 09:42:38 -0500 Subject: [PATCH 047/381] Add history notes. --- pkgs/racket-doc/scribblings/reference/sequences.scrbl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index 8cbaa0ff4d..6f9b6c0b36 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -790,7 +790,9 @@ If @racket[min-count] is a number, the stream is required to have at least that @examples[#:eval sequence-evaluator (for/list ([x (in-syntax #'(1 2 3))]) - x)]} + x)] + +@history[#:added "6.2.900.6"]} @defproc[(in-pairs [seq sequence?]) sequence?]{ Produces a 2-valued sequence whose pairs of elements are the successive @@ -801,6 +803,7 @@ If @racket[min-count] is a number, the stream is required to have at least that @examples[#:eval sequence-evaluator (for/list ([(a b) (in-pairs '((1 . a) (2 . b) (3 . c)))]) b) ] + @history[#:added "6.2.900.6"] } @defproc[(in-slice [length exact-positive-integer?] [seq sequence?]) @@ -811,6 +814,7 @@ If @racket[min-count] is a number, the stream is required to have at least that @examples[#:eval sequence-evaluator (for/list ([e (in-slice 3 (in-range 8))]) e) ] + @history[#:added "6.2.900.6"] } From 033d5afb192961da500906ff8c37124adb10cd6b Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 10 Aug 2015 16:03:54 -0500 Subject: [PATCH 048/381] Revert adding `in-pairs` to `racket/sequence`. `in-dict` is more general, and `for` loops optimize it already. --- .../racket-doc/scribblings/reference/sequences.scrbl | 12 ------------ pkgs/racket-test-core/tests/racket/sequence.rktl | 10 ---------- racket/collects/racket/sequence.rkt | 12 ------------ 3 files changed, 34 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index 6f9b6c0b36..de9abfd718 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -794,18 +794,6 @@ If @racket[min-count] is a number, the stream is required to have at least that @history[#:added "6.2.900.6"]} -@defproc[(in-pairs [seq sequence?]) sequence?]{ - Produces a 2-valued sequence whose pairs of elements are the successive - @racket[car]s and @racket[cdr]s of the elements of @racket[seq]. - Equivalent to - @racket[(in-parallel (sequence-lift car seq) (sequence-lift cdr seq))]. - - @examples[#:eval sequence-evaluator - (for/list ([(a b) (in-pairs '((1 . a) (2 . b) (3 . c)))]) b) - ] - @history[#:added "6.2.900.6"] -} - @defproc[(in-slice [length exact-positive-integer?] [seq sequence?]) sequence?]{ Returns a sequence whose elements are lists with the first @racket[length] diff --git a/pkgs/racket-test-core/tests/racket/sequence.rktl b/pkgs/racket-test-core/tests/racket/sequence.rktl index 2e24bd4578..2014191daf 100644 --- a/pkgs/racket-test-core/tests/racket/sequence.rktl +++ b/pkgs/racket-test-core/tests/racket/sequence.rktl @@ -268,16 +268,6 @@ ;; ---------------------------------------- ;; Additional sequence constructors -(test #t sequence? (in-pairs '())) -(test #t sequence? (in-pairs '((1 . 2) (3 . 4)))) -(test '() - values - (for/list ([(x y) (in-pairs '())]) - x)) -(test '(2 4 6) - values - (for/list ([(x y) (in-pairs '((1 . 1) (2 . 2) (3 . 3)))]) - (+ x y))) (test #t sequence? (in-slice 1 '())) (test '() values (for/list ([v (in-slice 1 '())]) v)) (test '((0 1)) values (for/list ([v (in-slice 3 (in-range 2))]) v)) diff --git a/racket/collects/racket/sequence.rkt b/racket/collects/racket/sequence.rkt index 1910365be2..cd68cd305c 100644 --- a/racket/collects/racket/sequence.rkt +++ b/racket/collects/racket/sequence.rkt @@ -23,7 +23,6 @@ sequence-count sequence/c in-syntax - in-pairs (contract-out [in-slice (exact-positive-integer? sequence? . -> . any)])) (define empty-sequence @@ -259,17 +258,6 @@ (or (stx->list stx) (raise-type-error 'in-syntax "stx-list" stx))) -(define (in-pairs seq) - (make-do-sequence - (λ () - (let-values ([(more? gen) (sequence-generate seq)]) - (values (λ (e) (let ([e (gen)]) (values (car e) (cdr e)))) - (λ (_) #t) - #t - (λ (_) (more?)) - (λ _ #t) - (λ _ #t)))))) - (define (in-slice k seq) (make-do-sequence (λ () From c50eeeecc9832201075703f72edf8d376e41aed8 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 13 Aug 2015 11:04:16 -0500 Subject: [PATCH 049/381] Fix history annotations. Version changed while the PR was up. --- pkgs/racket-doc/scribblings/reference/sequences.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index de9abfd718..7933574c63 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -792,7 +792,7 @@ If @racket[min-count] is a number, the stream is required to have at least that (for/list ([x (in-syntax #'(1 2 3))]) x)] -@history[#:added "6.2.900.6"]} +@history[#:added "6.2.900.9"]} @defproc[(in-slice [length exact-positive-integer?] [seq sequence?]) sequence?]{ @@ -802,7 +802,7 @@ If @racket[min-count] is a number, the stream is required to have at least that @examples[#:eval sequence-evaluator (for/list ([e (in-slice 3 (in-range 8))]) e) ] - @history[#:added "6.2.900.6"] + @history[#:added "6.2.900.9"] } From 3c5ed5d8e12c8c28715be69454e19909c1a01704 Mon Sep 17 00:00:00 2001 From: Alex Knauth Date: Tue, 9 Jun 2015 10:57:45 -0400 Subject: [PATCH 050/381] syntax-parse: keep more srclocs in attribute bindings to cooperate more with DrRacket check-syntax arrows --- .../syntax/parse/private/rep-data.rkt | 21 +++++++++++++++++-- racket/collects/syntax/parse/private/rep.rkt | 7 +++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/racket/collects/syntax/parse/private/rep-data.rkt b/racket/collects/syntax/parse/private/rep-data.rkt index 8b9b449bdc..977cc57bf5 100644 --- a/racket/collects/syntax/parse/private/rep-data.rkt +++ b/racket/collects/syntax/parse/private/rep-data.rkt @@ -286,10 +286,20 @@ expressions are duplicated, and may be evaluated in different scopes. (cond [(and (stxclass-colon-notation?) (regexp-match #rx"^([^:]*):(.+)$" (symbol->string (syntax-e id0)))) => (lambda (m) + (define-values [src ln col pos span] + (syntax-srcloc-values id0)) + (define id-str (cadr m)) + (define id-len (string-length id-str)) + (define suffix-str (caddr m)) + (define suffix-len (string-length suffix-str)) (define id - (datum->syntax id0 (string->symbol (cadr m)) id0 id0)) + (datum->syntax id0 (string->symbol id-str) + (list src ln col pos id-len) + id0)) (define suffix - (datum->syntax id0 (string->symbol (caddr m)) id0 id0)) + (datum->syntax id0 (string->symbol suffix-str) + (list src ln (and col (+ col id-len 1)) (and pos (+ pos id-len 1)) suffix-len) + id0)) (declenv-check-unbound decls id (syntax-e suffix) #:blame-declare? #t) (let ([suffix-entry (declenv-lookup decls suffix)]) @@ -300,6 +310,13 @@ expressions are duplicated, and may be evaluated in different scopes. (values id sc))])))] [else (values id0 #f)])) +(define (syntax-srcloc-values stx) + (values (syntax-source stx) + (syntax-line stx) + (syntax-column stx) + (syntax-position stx) + (syntax-span stx))) + ;; ---- (provide get-eh-alternative-set) diff --git a/racket/collects/syntax/parse/private/rep.rkt b/racket/collects/syntax/parse/private/rep.rkt index b2a651b4e7..a1aaf36230 100644 --- a/racket/collects/syntax/parse/private/rep.rkt +++ b/racket/collects/syntax/parse/private/rep.rkt @@ -812,7 +812,7 @@ (define (name->prefix id pfx) (cond [(wildcard? id) #f] [(epsilon? id) id] - [else (format-id id "~a~a" (syntax-e id) pfx)])) + [else (format-id id "~a~a" (syntax-e id) pfx #:source id)])) (define (name->bind id) (cond [(wildcard? id) #f] @@ -834,7 +834,10 @@ ;; prefix-attr-name : id symbol -> id (define (prefix-attr-name prefix name) - (format-id prefix "~a~a" (syntax-e prefix) name)) + (orig (format-id prefix "~a~a" (syntax-e prefix) name #:source prefix))) + +(define (orig stx) + (syntax-property stx 'original-for-check-syntax #t)) ;; ---- From 33cf7168350801038a0282fd593d6321c638d5b6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 12:32:34 -0600 Subject: [PATCH 051/381] include phantom bytes consistently in memory-use reports --- pkgs/racket-doc/scribblings/reference/memory.scrbl | 3 ++- racket/src/racket/gc2/newgc.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/memory.scrbl b/pkgs/racket-doc/scribblings/reference/memory.scrbl index bf529feca3..ccee0c33a4 100644 --- a/pkgs/racket-doc/scribblings/reference/memory.scrbl +++ b/pkgs/racket-doc/scribblings/reference/memory.scrbl @@ -224,7 +224,8 @@ with additional fields: @item{The @racket[pre-amount] field reports place-local memory use (i.e., not counting the memory use of child places) in bytes at - the time that the @tech{garbage collection} started.} + the time that the @tech{garbage collection} started. Additional + bytes registered via @racket[make-phantom-bytes] are included.} @item{The @racket[pre-admin-amount] is a larger number that includes memory use for the garbage collector's overhead, such as space diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index ebb3da8048..9c381792a7 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4006,6 +4006,7 @@ void GC_dump_with_traces(int flags, GCWARN((GCOUTF,"Allocated (+reserved) page sizes: %" PRIdPTR " (+%" PRIdPTR ")\n", gc->used_pages * APAGE_SIZE, mmu_memory_allocated(gc->mmu) - (gc->used_pages * APAGE_SIZE))); + GCWARN((GCOUTF,"Phantom bytes: %" PRIdPTR "\n", gc->phantom_count)); GCWARN((GCOUTF,"# of major collections: %" PRIdPTR "\n", gc->num_major_collects)); GCWARN((GCOUTF,"# of minor collections: %" PRIdPTR "\n", gc->num_minor_collects)); GCWARN((GCOUTF,"# of installed finalizers: %i\n", gc->num_fnls)); @@ -4946,7 +4947,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin old_mem_use = gc->memory_in_use; old_gen0 = gc->gen0.current_size; - old_mem_allocated = mmu_memory_allocated(gc->mmu); + old_mem_allocated = mmu_memory_allocated(gc->mmu) + gc->phantom_count; TIME_DECLS(); @@ -5166,7 +5167,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin park_for_inform_callback(gc); gc->GC_collect_inform_callback(is_master, gc->gc_full, old_mem_use + old_gen0, gc->memory_in_use, - old_mem_allocated, mmu_memory_allocated(gc->mmu), + old_mem_allocated, mmu_memory_allocated(gc->mmu)+gc->phantom_count, gc->child_gc_total); unpark_for_inform_callback(gc); } @@ -5176,7 +5177,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin lmi->full = gc->gc_full, lmi->pre_used = old_mem_use + old_gen0; lmi->post_used = gc->memory_in_use; - lmi->pre_admin = old_mem_allocated; + lmi->pre_admin = old_mem_allocated+gc->phantom_count; lmi->post_admin = mmu_memory_allocated(gc->mmu); } GC_propagate_hierarchy_memory_use(); From f3098a946a8faa75e4acbd02774f9ad711607d17 Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Wed, 12 Aug 2015 23:04:02 +0200 Subject: [PATCH 052/381] Fix an error in racket-test-core/number.rktl on OpenBSD-current/sparc64 "Errors were: (Section (got expected (call))) ((numbers) (0.0 -0.0 (# -0.0))) ((numbers) (125.0+0.0i 125.0-0.0i (# 125.00000000000023-0.0i))) ((numbers) (100.0+0.0i 100.0-0.0i (# 99.99999999999999-0.0i)))" --- racket/src/racket/sconfig.h | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/sconfig.h b/racket/src/racket/sconfig.h index bf2bb5c699..bc26e02c9a 100644 --- a/racket/src/racket/sconfig.h +++ b/racket/src/racket/sconfig.h @@ -378,6 +378,7 @@ # define MZ_USE_JIT_PPC # elif defined(__sparc64__) # define FLUSH_SPARC_REGISTER_WINDOWS +# define FMOD_CAN_RETURN_POS_ZERO # elif defined(__arm__) # define MZ_USE_JIT_ARM # define FFI_CALLBACK_NEED_INT_CLEAR From 12315ec96410d540afe9dc0de0e8d83347a2d51a Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Thu, 13 Aug 2015 13:43:36 -0600 Subject: [PATCH 053/381] using correct inspector for unresolved module --- racket/src/racket/src/resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index d5d947cc84..4181cfc5e6 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -4029,7 +4029,7 @@ Scheme_Object *unresolve_module(Scheme_Object *e, Unresolve_Info *ui) nm->exp_infos = m->exp_infos; nm->self_modidx = m->self_modidx; - nm->insp = m->insp; + nm->insp = m->prefix->src_insp_desc; nm->lang_info = m->lang_info; From 15eadbb86883ef855dc9d880db70735e4bf614d7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 14:24:36 -0600 Subject: [PATCH 054/381] copy-directory/files: add `#:preserve-links?` argument --- .../scribblings/reference/filesystem.scrbl | 14 +++++++++----- racket/collects/racket/file.rkt | 14 ++++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index fdaa57e98a..d5c4edeb72 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -936,20 +936,24 @@ Displays each element of @racket[lst] to @racket[path], adding @racket[open-output-file].} @defproc[(copy-directory/files [src path-string?] [dest path-string?] - [#:keep-modify-seconds? keep-modify-seconds? #f]) + [#:keep-modify-seconds? keep-modify-seconds? #f] + [#:preserve-links? preserve-links? #f]) void?]{ Copies the file or directory @racket[src] to @racket[dest], raising @racket[exn:fail:filesystem] if the file or directory cannot be copied, possibly because @racket[dest] exists already. If @racket[src] is a directory, the copy applies recursively to the directory's -content. If a source is a link, the target of the link is copied -rather than the link itself. +content. If a source is a link and @racket[preserve-links?] is @racket[#f], +the target of the link is copied rather than the link itself; if +@racket[preserve-links?] is @racket[#t], the link is copied. If @racket[keep-modify-seconds?] is @racket[#f], then file copies -keep only the properties kept by @racket[copy-file], If +keep only the properties kept by @racket[copy-file]. If @racket[keep-modify-seconds?] is true, then each file copy also keeps -the modification date of the original.} +the modification date of the original. + +@history[#:changed "6.2.900.9" @elem{Added the @racket[#:preserve-links?] argument.}]} @defproc[(delete-directory/files [path path-string?] diff --git a/racket/collects/racket/file.rkt b/racket/collects/racket/file.rkt index 7a5bd1bd34..47938ed822 100644 --- a/racket/collects/racket/file.rkt +++ b/racket/collects/racket/file.rkt @@ -64,15 +64,21 @@ (define (raise-not-a-file-or-directory who path) (raise (make-exn:fail:filesystem - (format "~a: encountered ~a, neither a file nor a directory" + (format "~a: encountered path that is neither file nor directory\n path: ~a" who path) (current-continuation-marks)))) -(define (copy-directory/files src dest - #:keep-modify-seconds? [keep-modify-seconds? #f]) +(define (copy-directory/files src dest + #:keep-modify-seconds? [keep-modify-seconds? #f] + #:preserve-links? [preserve-links? #f]) (let loop ([src src] [dest dest]) - (cond [(file-exists? src) + (cond [(and preserve-links? + (link-exists? src)) + (make-file-or-directory-link + (resolve-path src) + dest)] + [(file-exists? src) (copy-file src dest) (when keep-modify-seconds? (file-or-directory-modify-seconds From 07816f2ca4baea004ea02486fcdceeeb542a3181 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Thu, 13 Aug 2015 10:27:20 -0300 Subject: [PATCH 055/381] Use scheme_getenv in eval.c --- racket/src/racket/src/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index f5d6c3a616..4b95814f19 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -382,7 +382,7 @@ scheme_init_eval (Scheme_Env *env) GLOBAL_PARAMETER("eval-jit-enabled", use_jit, MZCONFIG_USE_JIT, env); GLOBAL_PARAMETER("compile-context-preservation-enabled", disallow_inline, MZCONFIG_DISALLOW_INLINE, env); - if (getenv("PLT_VALIDATE_COMPILE")) { + if (scheme_getenv("PLT_VALIDATE_COMPILE")) { /* Enables validation of bytecode as it is generated, to double-check that the compiler is producing valid bytecode as it should. */ @@ -392,7 +392,7 @@ scheme_init_eval (Scheme_Env *env) { /* Enables re-running the optimizer N times on every compilation. */ const char *s; - s = getenv("PLT_RECOMPILE_COMPILE"); + s = scheme_getenv("PLT_RECOMPILE_COMPILE"); if (s) { int i = 0; while ((s[i] >= '0') && (s[i] <= '9')) { From cfa1d391662d2401197600c4643372e6fcd61e7e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 17:06:10 -0600 Subject: [PATCH 056/381] add `compiler/exe-dylib-path` Provide a clean interface to a private library for updating dynamic-library paths in Mac executables. --- .../scribblings/raco/exe-dylib-path.scrbl | 36 +++++++++++++++++++ pkgs/racket-doc/scribblings/raco/exe.scrbl | 2 ++ racket/collects/compiler/exe-dylib-path.rkt | 17 +++++++++ racket/collects/compiler/private/macfw.rkt | 24 ++++++------- 4 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl create mode 100644 racket/collects/compiler/exe-dylib-path.rkt diff --git a/pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl b/pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl new file mode 100644 index 0000000000..1b223ff401 --- /dev/null +++ b/pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl @@ -0,0 +1,36 @@ +#lang scribble/manual +@(require "common.rkt" + (for-label racket/base + racket/contract + compiler/exe-dylib-path)) + +@title[#:tag "exe-dylib-path"]{Mac OS X Dynamic Library Paths} + +@defmodule[compiler/exe-dylib-path]{The +@racketmodname[compiler/exe-dylib-path] library provides functions for +reading and adjusting dynamic-library references in a Mac OS X +executable.} + +@history[#:added "6.2.900.9"] + +@defproc[(find-matching-library-path [exe-path path-string?] + [library-str string?]) + (or/c #f string?)]{ + +Searches dynamic-linking information in @racket[exe-path] for a +library reference whose name includes @racket[library-str] and returns +the executable's path to the library for the first match. If no match is +found, the result is @racket[#f].} + +@defproc[(update-matching-library-path [exe-path path-string?] + [library-str string?] + [library-path-str string?]) + void?]{ + +Searches dynamic-linking information in @racket[exe-path] for each +library reference whose name includes @racket[library-str] and replaces +the executable's path to that library with @racket[library-path-str]. + +A single match is expected, and the update assumes enough space for +the new path, perhaps because the executable is linked with +@Flag{headerpad_max_install_names}.} diff --git a/pkgs/racket-doc/scribblings/raco/exe.scrbl b/pkgs/racket-doc/scribblings/raco/exe.scrbl index df90876053..3e957c98b4 100644 --- a/pkgs/racket-doc/scribblings/raco/exe.scrbl +++ b/pkgs/racket-doc/scribblings/raco/exe.scrbl @@ -176,3 +176,5 @@ The @exec{raco exe} command accepts the following command-line flags: @include-section["exe-api.scrbl"] @include-section["launcher.scrbl"] +@include-section["exe-dylib-path.scrbl"] + diff --git a/racket/collects/compiler/exe-dylib-path.rkt b/racket/collects/compiler/exe-dylib-path.rkt new file mode 100644 index 0000000000..3bbafda2f9 --- /dev/null +++ b/racket/collects/compiler/exe-dylib-path.rkt @@ -0,0 +1,17 @@ +#lang racket/base +(require racket/contract/base + "private/macfw.rkt") + +(provide + (contract-out + [find-matching-library-path (path-string? string? . -> . (or/c #f string?))] + [update-matching-library-path (path-string? string? string? . -> . void?)])) + +(define (find-matching-library-path exe str) + (get-current-framework-path exe str)) + +(define (update-matching-library-path exe str new-str) + (update-framework-path new-str #:as-given? #t + exe + #f + #:matching (list str))) diff --git a/racket/collects/compiler/private/macfw.rkt b/racket/collects/compiler/private/macfw.rkt index a28826ea10..65536366d1 100644 --- a/racket/collects/compiler/private/macfw.rkt +++ b/racket/collects/compiler/private/macfw.rkt @@ -14,7 +14,10 @@ (vector-ref v 1) (equal? (vector-ref v 2) "mred")))) - (define (update-framework-path fw-path dest mred?) + (define (update-framework-path fw-path #:as-given? [as-given? #f] + dest + mred? + #:matching [matchings '("Racket")]) (let ([dest (if (path? dest) (path->string dest) dest)]) @@ -25,9 +28,11 @@ "")] [old-path (or orig (format "~a.framework/Versions/~a~a/~a" p (version) 3m p))] - [new-path (format "~a~a.framework/Versions/~a~a/~a" - fw-path - p (version) 3m p)]) + [new-path (if as-given? + (format "~a" fw-path) + (format "~a~a.framework/Versions/~a~a/~a" + fw-path + p (version) 3m p))]) (get/set-dylib-path dest (byte-regexp (bytes-append @@ -36,16 +41,11 @@ (regexp-quote old-path)) #"$")) (string->bytes/utf-8 new-path)))) - '("Racket")))) + matchings))) (define (get-current-framework-path dest p) (let ([v (get/set-dylib-path dest (byte-regexp (string->bytes/utf-8 p)) #f)]) - (if (pair? v) - (bytes->string/utf-8 (car v)) - (begin - (eprintf "warning: cannot find existing link for ~a in ~a\n" - p dest) - #f))))) - + (and (pair? v) + (bytes->string/utf-8 (car v)))))) From c57fb2d1ce6dcc22e467cdc710ff6b32a2b83a44 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 18:20:24 -0600 Subject: [PATCH 057/381] fix `setup/collection-search` test --- pkgs/racket-test/tests/setup/collection-search.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/setup/collection-search.rkt b/pkgs/racket-test/tests/setup/collection-search.rkt index a9f1cb81bc..6a94053441 100644 --- a/pkgs/racket-test/tests/setup/collection-search.rkt +++ b/pkgs/racket-test/tests/setup/collection-search.rkt @@ -28,7 +28,7 @@ (list 'racket 'racket/base 'compiler/compilation-path - 'tests/compiler/collection-search)) + 'tests/setup/collection-search)) ;; Try to find a module in every installed collection: (define cache (make-hash)) From e82e61e84ca1b8bd47ff89523d6f8978fdda91a7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Aug 2015 18:22:51 -0600 Subject: [PATCH 058/381] restore needed call in unresolver Add back a call incorrectly removed in bd82646d81. --- racket/src/racket/src/resolve.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 4181cfc5e6..df6d5575bd 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -4399,6 +4399,7 @@ static Scheme_Object *unresolve_expr_2(Scheme_Object *e, Unresolve_Info *ui, int pos = unresolve_stack_push(ui, 1, 0, 0); b = unresolve_expr_2(wcm->body, ui, 0); if (!b) return_NULL; + (void)unresolve_stack_pop(ui, pos, 1); wcm2 = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark); wcm2->so.type = scheme_with_immed_mark_type; From 111a7e085de61c2b613f4e4933d120e0376eaba2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 14 Aug 2015 07:23:33 -0600 Subject: [PATCH 059/381] fix prefab checking in printer Mishandling of a chaproned prefab when, for example, determining whether to use quoted printing caused the `tests/compiler/zo` test to sometimes fail. --- racket/src/racket/src/print.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index 5228663ab4..38c338849d 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -159,7 +159,9 @@ static Scheme_Object *writable_struct_subs(Scheme_Object *s, int for_write, Prin #define print_compact(pp, v) print_this_string(pp, &compacts[v], 0, 1) #define PRINTABLE_STRUCT(obj, pp) (scheme_inspector_sees_part(obj, pp->inspector, -1)) -#define SCHEME_PREFABP(obj) (((Scheme_Structure *)(obj))->stype->prefab_key) +#define SCHEME_PREFABP(obj) (SCHEME_CHAPERONEP(obj) \ + ? ((Scheme_Structure *)SCHEME_CHAPERONE_VAL(obj))->stype->prefab_key \ + : ((Scheme_Structure *)(obj))->stype->prefab_key) #define SCHEME_HASHTPx(obj) ((SCHEME_HASHTP(obj) && !(MZ_OPT_HASH_KEY(&(((Scheme_Hash_Table *)obj)->iso)) & 0x1))) #define SCHEME_CHAPERONE_HASHTPx(obj) (SCHEME_HASHTPx(obj) \ @@ -2508,8 +2510,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, } else if (SCHEME_CHAPERONE_STRUCTP(obj)) { - if (compact && (SCHEME_PREFABP(obj) || (SCHEME_CHAPERONEP(obj) - && SCHEME_PREFABP(SCHEME_CHAPERONE_VAL(obj))))) { + if (compact && SCHEME_PREFABP(obj)) { Scheme_Object *vec, *prefab; print_compact(pp, CPT_PREFAB); prefab = scheme_prefab_struct_key(obj); From dbd5470805d212fa5544571ee50669fdddf73308 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 14 Aug 2015 07:45:47 -0600 Subject: [PATCH 060/381] move `call/cc` and `call/ec` to `racket/private/more-scheme` Those aliases were moved out of `#%kernel` as part of the determinstic-bytecode changes, but putting them in `racket/private/pre-base` meant that they weren't included in `mzscheme` or Pretty Big. The new location is with `let/cc`, which makes more sense, and makes them picked up by `mzscheme` and Pretty Big. --- racket/collects/racket/private/more-scheme.rkt | 5 ++++- racket/collects/racket/private/pre-base.rkt | 6 +----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/racket/collects/racket/private/more-scheme.rkt b/racket/collects/racket/private/more-scheme.rkt index 02e16ed2ff..b1511ce779 100644 --- a/racket/collects/racket/private/more-scheme.rkt +++ b/racket/collects/racket/private/more-scheme.rkt @@ -298,6 +298,9 @@ stx (let-values ([(temp ...) expr]) (set! id temp) ...)))]))) + + (define-values (call/cc) call-with-current-continuation) + (define-values (call/ec) call-with-escape-continuation) (define-syntax let/cc (lambda (stx) @@ -386,6 +389,6 @@ (rename break-paramz? break-parameterization?) with-handlers with-handlers* call-with-exception-handler set!-values - let/cc fluid-let time + let/cc call/cc call/ec fluid-let time log-fatal log-error log-warning log-info log-debug define-logger hash-ref! hash-has-key? hash-update hash-update!)) diff --git a/racket/collects/racket/private/pre-base.rkt b/racket/collects/racket/private/pre-base.rkt index a1b5d93520..e695d4bf08 100644 --- a/racket/collects/racket/private/pre-base.rkt +++ b/racket/collects/racket/private/pre-base.rkt @@ -149,9 +149,6 @@ stx) (raise-syntax-error #f "bad syntax" stx))))) - (define-values (call/cc) call-with-current-continuation) - (define-values (call/ec) call-with-escape-continuation) - (#%provide (all-from-except "more-scheme.rkt" old-case fluid-let) (all-from-except "misc.rkt" collection-path collection-file-path) (all-from "define.rkt") @@ -210,5 +207,4 @@ define-struct/derived struct-field-index struct-copy - double-flonum? - call/cc call/ec)) + double-flonum?)) From 0caf0796372811d71573459b76119cec960bb877 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 14 Aug 2015 16:48:20 -0600 Subject: [PATCH 061/381] add `syntax-local-lift-module` --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/stx-trans.scrbl | 29 +- pkgs/racket-test-core/tests/racket/macro.rktl | 60 + .../racket-test-core/tests/racket/module.rktl | 48 + racket/src/racket/src/compenv.c | 83 +- racket/src/racket/src/compile.c | 5 +- racket/src/racket/src/cstartup.inc | 3074 ++++++++--------- racket/src/racket/src/env.c | 21 + racket/src/racket/src/eval.c | 23 +- racket/src/racket/src/module.c | 169 +- racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schpriv.h | 6 +- racket/src/racket/src/schvers.h | 4 +- 13 files changed, 1913 insertions(+), 1613 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 8590b2af27..339b282d45 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.9") +(define version "6.2.900.10") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index 8b87be0dd3..b2a26def63 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -348,7 +348,12 @@ forms, and the expansion of @racket[stx] is the last expression in the @racket[begin]. The @racket[lift-ctx] value is reported by @racket[syntax-local-lift-context] during local expansion. The lifted expressions are not expanded, but instead left as provided in the -@racket[begin] form.} +@racket[begin] form. + +If @racket[context-v] is @racket['top-level] or @racket['module], then +@racket[module] forms can appear in the result as added via +@racket[syntax-local-lift-module]. If @racket[context-v] is +@racket['module], then @racket[module*] forms can appear, too.} @defproc[(local-transformer-expand/capture-lifts [stx any/c] @@ -578,6 +583,28 @@ for caching lift information to avoid redundant lifts. @transform-time[]} +@defproc[(syntax-local-lift-module [stx syntax?]) + void?]{ + +Cooperates with the @racket[module] form or top-level expansion to add +@racket[stx] as a module declaration in the enclosing module or top-level. +The @racket[stx] form must start with @racket[module] or @racket[module*], +where the latter is only allowed within the expansion of a module. + +The module is not immediately declared when +@racket[syntax-local-lift-module] returns. Instead, the module +declaration is recorded for processing when expansion returns to the +enclosing module body or top-level sequence. + +@transform-time[] If the current expression being transformed is not +within a @racket[module] form or within a top-level expansion, then +the @exnraise[exn:fail:contract]. If @racket[stx] form does start with +@racket[module] or @racket[module*], or if it starts with @racket[module*] +in a top-level context, the @exnraise[exn:fail:contract]. + +@history[#:added "6.2.900.10"]} + + @defproc[(syntax-local-lift-module-end-declaration [stx syntax?]) void?]{ diff --git a/pkgs/racket-test-core/tests/racket/macro.rktl b/pkgs/racket-test-core/tests/racket/macro.rktl index 44a373b56e..669056f3e1 100644 --- a/pkgs/racket-test-core/tests/racket/macro.rktl +++ b/pkgs/racket-test-core/tests/racket/macro.rktl @@ -1019,6 +1019,66 @@ (eval `(require 'm))) (test "2\n" get-output-string o)) +(parameterize ([current-namespace (make-base-namespace)]) + (eval `(module m racket/base + (require (for-syntax racket/base)) + (define x 10) + (let-syntax ([x (syntax-local-lift-module #'(module m racket/base + (provide x) + (define x 10)))]) + (void)))) + (test 10 eval `(dynamic-require '(submod 'm m) 'x))) + +;; ---------------------------------------- +;; Check module lifting in a top-level context + +(define-syntax (do-lift-example-1 stx) + (syntax-local-lift-module + #'(module lift-example-1 racket/base + (provide x) + (define x 10))) + #'(void)) +(do-lift-example-1) +(test 10 dynamic-require ''lift-example-1 'x) + +(test '(begin + (module lift-example-1 racket/base + (provide x) + (define x 10)) + (#%app void)) + 'local-expand/capture-lifts + (let-syntax ([quote-local-expand + (lambda (stx) + (syntax-case stx () + [(_ e) + #`(quote #,(local-expand/capture-lifts #'e 'top-level null))]))]) + (quote-local-expand (do-lift-example-1)))) + +(define-syntax (do-lift-example-1* stx) + (syntax-local-lift-module + #'(module* lift-example-1* racket/base + (provide x) + (define x 10))) + #'(void)) + +(err/rt-test (expand '(do-lift-example-1*)) + (lambda (exn) + (and (exn:fail:contract? exn) + (regexp-match #rx"cannot lift.*module[*]" (exn-message exn))))) + +(test '(begin + (module* lift-example-1* racket/base + (provide x) + (define x 10)) + (#%app void)) + 'local-expand/capture-lifts + (let-syntax ([quote-local-expand + (lambda (stx) + (syntax-case stx () + [(_ e) + #`(quote #,(local-expand/capture-lifts #'e 'module null))]))]) + (quote-local-expand (do-lift-example-1*)))) + ;; ---------------------------------------- ;; Lifting should not introduce `#%top` around ;; the reference to the lifted identifier: diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 2384ca4427..1219adc878 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1430,6 +1430,54 @@ case of module-leve bindings; it doesn't cover local bindings. (test #t syntax? (expand-syntax (expand lifted-require-of-submodule))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check module lifting + +(module module-lift-example-1 racket/base + (require (for-syntax racket/base)) + (define-syntax (m stx) + (syntax-local-lift-module + #'(module m racket/base + (provide x) + (define x 10))) + #'(begin + (require 'm) + (define out x) + (provide out))) + (m)) + +(test 10 dynamic-require ''module-lift-example-1 'out) + +(module module-lift-example-2 racket/base + (require (for-syntax racket/base)) + (define-syntax (m stx) + (syntax-local-lift-module #'(module* sub #f + (provide s) + (define s (add1 a)))) + #'(void)) + (m) + (define a 1)) + +(test 2 dynamic-require '(submod 'module-lift-example-2 sub) 's) + + +(module module-lift-example-3 racket/base + (require (for-syntax racket/base)) + (define-syntax (m stx) + (syntax-local-lift-module #'(module m racket/base + (provide x) + (define x 11))) + (syntax-local-lift-module-end-declaration + #'(let () + (local-require (submod "." m)) + (set! out x))) + #'(void)) + (define out -10) + (m) + (provide out)) + +(test 11 dynamic-require ''module-lift-example-3 'out) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check addition of 'disappeared-use by `provide` diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index 5ba2ade4c9..d9e1ce51fe 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -398,7 +398,8 @@ scheme_add_compilation_binding(int index, Scheme_Object *val, Scheme_Comp_Env *f void scheme_frame_captures_lifts(Scheme_Comp_Env *env, Scheme_Lift_Capture_Proc cp, Scheme_Object *data, Scheme_Object *end_stmts, Scheme_Object *context_key, - Scheme_Object *requires, Scheme_Object *provides) + Scheme_Object *requires, Scheme_Object *provides, + Scheme_Object *module_lifts) { Scheme_Lift_Capture_Proc *pp; Scheme_Object *vec; @@ -406,7 +407,7 @@ void scheme_frame_captures_lifts(Scheme_Comp_Env *env, Scheme_Lift_Capture_Proc pp = (Scheme_Lift_Capture_Proc *)scheme_malloc_atomic(sizeof(Scheme_Lift_Capture_Proc)); *pp = cp; - vec = scheme_make_vector(8, NULL); + vec = scheme_make_vector(9, NULL); SCHEME_VEC_ELS(vec)[0] = scheme_null; SCHEME_VEC_ELS(vec)[1] = (Scheme_Object *)pp; SCHEME_VEC_ELS(vec)[2] = data; @@ -415,6 +416,7 @@ void scheme_frame_captures_lifts(Scheme_Comp_Env *env, Scheme_Lift_Capture_Proc SCHEME_VEC_ELS(vec)[5] = (requires ? requires : scheme_false); SCHEME_VEC_ELS(vec)[6] = scheme_null; /* accumulated requires */ SCHEME_VEC_ELS(vec)[7] = provides; + SCHEME_VEC_ELS(vec)[8] = module_lifts; /* #f => disallowed; #t or (void) => add to slot 0; (void) => `module*` allowed */ env->lifts = vec; } @@ -433,7 +435,7 @@ void scheme_propagate_require_lift_capture(Scheme_Comp_Env *orig_env, Scheme_Com p = scheme_make_raw_pair(NULL, (Scheme_Object *)orig_env); - vec = scheme_make_vector(8, NULL); + vec = scheme_make_vector(9, NULL); SCHEME_VEC_ELS(vec)[0] = scheme_false; SCHEME_VEC_ELS(vec)[1] = scheme_void; SCHEME_VEC_ELS(vec)[2] = scheme_void; @@ -442,6 +444,7 @@ void scheme_propagate_require_lift_capture(Scheme_Comp_Env *orig_env, Scheme_Com SCHEME_VEC_ELS(vec)[5] = p; /* (rcons NULL env) => continue with env */ SCHEME_VEC_ELS(vec)[6] = scheme_null; SCHEME_VEC_ELS(vec)[7] = scheme_false; + SCHEME_VEC_ELS(vec)[8] = scheme_false; env->lifts = vec; } @@ -457,6 +460,11 @@ Scheme_Object *scheme_frame_get_end_statement_lifts(Scheme_Comp_Env *env) return SCHEME_VEC_ELS(env->lifts)[3]; } +Scheme_Object *scheme_frame_get_modules(Scheme_Comp_Env *env) +{ + return SCHEME_VEC_ELS(env->lifts)[8]; +} + Scheme_Object *scheme_frame_get_require_lifts(Scheme_Comp_Env *env) { return SCHEME_VEC_ELS(env->lifts)[6]; @@ -2087,6 +2095,18 @@ Scheme_Comp_Env *scheme_get_module_lift_env(Scheme_Comp_Env *env) return env; } +static Scheme_Comp_Env *get_lift_env_for_module(Scheme_Comp_Env *env) +{ + while (env) { + if ((env->lifts) + && SCHEME_TRUEP(SCHEME_VEC_ELS(env->lifts)[8])) + break; + env = env->next; + } + + return env; +} + Scheme_Object * scheme_local_lift_end_statement(Scheme_Object *expr, Scheme_Object *local_scope, Scheme_Comp_Env *env) { @@ -2113,6 +2133,63 @@ scheme_local_lift_end_statement(Scheme_Object *expr, Scheme_Object *local_scope, return scheme_void; } +Scheme_Object * +scheme_local_lift_module(Scheme_Object *expr, Scheme_Object *local_scope, Scheme_Comp_Env *env) +{ + Scheme_Object *pr; + Scheme_Object *orig_expr; + int star_ok, slot; + + env = get_lift_env_for_module(env); + + if (!env) + scheme_contract_error("syntax-local-lift-module", + "not currently transforming within a module declaration or top level", + NULL); + + if (local_scope) + expr = scheme_stx_flip_scope(expr, local_scope, scheme_env_phase(env->genv)); + orig_expr = expr; + + star_ok = !SAME_OBJ(scheme_true, SCHEME_VEC_ELS(env->lifts)[8]); + + if (SCHEME_STX_PAIRP(expr)) { + pr = SCHEME_STX_CAR(expr); + if (scheme_stx_free_eq3(pr, scheme_module_stx, scheme_env_phase(env->genv), scheme_make_integer(0))) { + /* ok */ + } else if (scheme_stx_free_eq3(pr, scheme_modulestar_stx, scheme_env_phase(env->genv), scheme_make_integer(0))) { + if (!star_ok) + scheme_contract_error("syntax-local-lift-module", + "cannot lift `module*' to a top-level context", + "syntax", 1, expr, + NULL); + /* otherwise, ok */ + } else + pr = NULL; + } else + pr = NULL; + + if (!pr) + scheme_contract_error("syntax-local-lift-module", + "not a module declaration", + "syntax", 1, expr, + NULL); + + /* Add to separate list or mingle with definitions? */ + if (SCHEME_NULLP(SCHEME_VEC_ELS(env->lifts)[8]) + || SCHEME_PAIRP(SCHEME_VEC_ELS(env->lifts)[8])) + slot = 8; + else + slot = 0; + + pr = scheme_make_pair(expr, SCHEME_VEC_ELS(env->lifts)[slot]); + SCHEME_VEC_ELS(env->lifts)[slot] = pr; + + SCHEME_EXPAND_OBSERVE_LIFT_STATEMENT(scheme_get_expand_observe(), orig_expr); + + return scheme_void; +} + Scheme_Object *scheme_local_lift_require(Scheme_Object *form, Scheme_Object *orig_form, intptr_t phase, Scheme_Object *local_scope, Scheme_Comp_Env *cenv) { diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 029ac93d48..431033e2d2 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -3508,7 +3508,8 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem while (1) { scheme_frame_captures_lifts(env, scheme_make_lifted_defn, scheme_sys_wraps(env), - scheme_false, scheme_top_level_lifts_key(env), scheme_null, scheme_false); + scheme_false, scheme_top_level_lifts_key(env), scheme_null, + scheme_false, scheme_true); if (rec[drec].comp) { scheme_init_compile_recs(rec, drec, recs, 1); @@ -5589,7 +5590,7 @@ compile_expand_expr_lift_to_let(Scheme_Object *form, Scheme_Comp_Env *env, context_key = scheme_generate_lifts_key(); scheme_frame_captures_lifts(inserted, scheme_pair_lifted, (Scheme_Object *)ip, scheme_false, - context_key, NULL, scheme_false); + context_key, NULL, scheme_false, scheme_false); if (rec[drec].comp) { scheme_init_compile_recs(rec, drec, recs, 2); diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index b486bc703a..f1a704a83a 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,842 +1,863 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,0,1,0,0,8,0, -18,0,22,0,26,0,31,0,38,0,42,0,47,0,59,0,66,0,69,0,82, -0,89,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159,0, -173,0,180,0,202,0,204,0,218,0,246,0,251,0,255,0,72,1,79,1,90, -1,128,1,135,1,144,1,177,1,210,1,16,2,21,2,102,2,107,2,112,2, -133,2,30,3,51,3,104,3,173,3,242,3,132,4,24,5,35,5,118,5,0, -0,147,7,0,0,3,1,5,105,110,115,112,48,71,35,37,109,105,110,45,115, -116,120,29,11,11,11,65,97,110,100,66,99,111,110,100,68,100,101,102,105,110, -101,65,108,101,116,66,108,101,116,42,73,108,101,116,42,45,118,97,108,117,101, -115,68,108,101,116,114,101,99,64,111,114,74,112,97,114,97,109,101,116,101,114, -105,122,101,68,117,110,108,101,115,115,66,119,104,101,110,70,104,101,114,101,45, -115,116,120,67,113,117,111,116,101,29,94,2,16,70,35,37,107,101,114,110,101, -108,11,29,94,2,16,70,35,37,112,97,114,97,109,122,11,64,105,102,67,98, -101,103,105,110,72,108,101,116,45,118,97,108,117,101,115,63,120,75,108,101,116, -114,101,99,45,118,97,108,117,101,115,68,108,97,109,98,100,97,1,20,112,97, -114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,63,118,75, -100,101,102,105,110,101,45,118,97,108,117,101,115,38,28,16,3,93,16,2,29, -11,11,11,2,3,2,29,93,143,16,5,39,2,31,40,2,34,2,2,39,38, -29,93,2,30,36,30,0,39,36,31,1,145,40,143,2,32,16,4,2,17,39, -39,2,1,143,2,32,16,4,2,18,39,39,2,1,16,22,2,4,2,33,2, -5,2,33,2,6,2,33,2,7,2,33,2,8,2,33,2,9,2,33,2,10, -2,33,2,11,2,33,2,12,2,33,2,13,2,33,2,14,2,33,38,32,143, -2,31,2,29,38,33,93,143,2,32,143,2,1,2,3,36,34,2,144,40,143, -2,35,16,4,2,17,40,39,2,1,16,2,2,15,93,143,2,35,147,2,1, -2,3,40,2,15,143,2,3,40,2,15,38,35,143,2,34,2,29,18,143,66, -104,101,114,101,2,28,27,248,22,164,4,195,249,22,157,4,80,143,42,39,251, -22,90,2,19,248,22,102,199,12,249,22,80,2,20,248,22,104,201,27,248,22, -164,4,195,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,102,199,249, -22,80,2,20,248,22,104,201,12,27,248,22,82,248,22,164,4,196,28,248,22, -88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,162,20,193, -249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,162,20,199,249,22,80, -2,4,248,22,163,20,201,11,18,143,10,2,28,27,248,22,82,248,22,164,4, -196,28,248,22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248, -22,162,20,193,249,22,157,4,80,143,42,39,250,22,90,2,21,248,22,90,249, -22,90,248,22,90,2,22,248,22,162,20,201,251,22,90,2,19,2,22,2,22, -249,22,80,2,11,248,22,163,20,204,18,143,11,2,28,248,22,164,4,193,27, -248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22,163,20,195,27, -248,22,82,248,22,164,4,23,197,1,249,22,157,4,80,143,42,39,28,248,22, -64,248,22,158,4,248,22,81,23,198,2,27,249,22,2,32,0,88,148,8,36, -40,46,11,9,222,33,43,248,22,164,4,248,22,102,23,200,2,250,22,90,2, -23,248,22,90,249,22,90,248,22,90,248,22,162,20,23,204,2,250,22,91,2, -24,249,22,2,22,81,23,204,2,248,22,104,23,206,2,249,22,80,248,22,162, -20,23,202,1,249,22,2,22,102,23,200,1,250,22,91,2,21,249,22,2,32, -0,88,148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,162,20,201, -248,22,163,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196, -248,22,163,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80, -143,42,39,250,22,91,2,23,249,22,2,32,0,88,148,8,36,40,50,11,9, -222,33,46,248,22,164,4,248,22,81,201,248,22,163,20,198,27,248,22,82,248, -22,164,4,196,27,248,22,164,4,248,22,81,195,249,22,157,4,80,143,43,39, -28,248,22,88,195,250,22,91,2,21,9,248,22,163,20,199,250,22,90,2,7, -248,22,90,248,22,81,199,250,22,91,2,8,248,22,163,20,201,248,22,163,20, -202,27,248,22,82,248,22,164,4,196,27,248,22,164,4,248,22,81,195,249,22, -157,4,80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,163,20, -199,250,22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22,163, -20,201,248,22,163,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249,22, -1,22,94,249,22,2,22,164,4,248,22,164,4,248,22,81,199,248,22,185,4, -249,22,157,4,80,143,44,39,251,22,90,1,22,119,105,116,104,45,99,111,110, -116,105,110,117,97,116,105,111,110,45,109,97,114,107,2,25,250,22,91,1,23, -101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105, -111,110,21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97, -114,107,45,115,101,116,45,102,105,114,115,116,11,2,25,202,250,22,91,2,21, -9,248,22,163,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193,20, -14,144,40,39,40,249,22,157,4,80,143,42,39,27,248,22,164,4,248,22,81, -197,28,249,22,169,9,64,61,62,248,22,158,4,248,22,102,196,250,22,90,2, -21,248,22,90,249,22,90,21,93,2,26,248,22,162,20,199,250,22,91,2,5, -249,22,90,2,26,249,22,90,248,22,111,203,2,26,248,22,163,20,202,251,22, -90,2,19,28,249,22,169,9,248,22,158,4,248,22,162,20,200,66,101,108,115, -101,10,248,22,162,20,197,250,22,91,2,21,9,248,22,163,20,200,249,22,80, -2,5,248,22,163,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248,22, -82,248,22,164,4,196,249,22,157,4,80,143,42,39,28,248,22,64,248,22,158, -4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,162,20,199,248,22,102, -198,27,248,22,158,4,248,22,162,20,197,250,22,90,2,27,248,22,90,248,22, -81,197,250,22,91,2,24,248,22,163,20,199,248,22,163,20,202,144,39,20,121, -145,2,1,39,16,1,11,16,0,20,27,15,61,9,2,2,2,2,2,3,11, -11,11,11,9,9,11,11,11,10,39,80,143,39,39,20,121,145,2,1,39,16, -0,16,0,41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4,2,5, -2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,16,11,11, -11,11,11,11,11,11,11,11,11,11,16,11,2,4,2,5,2,6,2,7,2, -8,2,9,2,10,2,11,2,12,2,13,2,14,39,50,40,16,0,39,16,1, -2,15,40,11,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16, -0,16,0,39,39,16,12,16,5,11,20,15,16,2,20,14,144,39,39,40,80, -143,39,39,39,20,121,145,2,1,39,16,1,2,15,16,1,33,36,10,16,5, -2,13,88,148,8,36,40,56,40,9,223,0,33,37,39,20,121,145,2,1,39, -16,1,2,15,16,0,11,16,5,2,14,88,148,8,36,40,56,40,9,223,0, -33,38,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,4,88, -148,8,36,40,56,42,9,223,0,33,39,39,20,121,145,2,1,39,16,1,2, -15,16,1,33,40,11,16,5,2,11,88,148,8,36,40,59,42,9,223,0,33, -41,39,20,121,145,2,1,39,16,1,2,15,16,1,33,42,11,16,5,2,7, -88,148,8,36,40,61,40,9,223,0,33,45,39,20,121,145,2,1,39,16,1, -2,15,16,0,11,16,5,2,10,88,148,8,36,40,56,40,9,223,0,33,47, -39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,8,88,148,8, -36,40,57,40,9,223,0,33,48,39,20,121,145,2,1,39,16,1,2,15,16, -0,11,16,5,2,9,88,148,8,36,40,57,40,9,223,0,33,49,39,20,121, -145,2,1,39,16,1,2,15,16,0,11,16,5,2,12,88,148,8,36,40,59, -40,9,223,0,33,50,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16, -5,2,5,88,148,8,36,40,61,42,9,223,0,33,51,39,20,121,145,2,1, -39,16,1,2,15,16,1,33,52,11,16,5,2,6,88,148,8,36,40,57,40, -9,223,0,33,53,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,0, -94,2,17,2,18,93,2,17,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 2091); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,0,1,0,0,8, +0,18,0,22,0,26,0,31,0,38,0,42,0,47,0,59,0,66,0,69,0, +82,0,89,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159, +0,173,0,180,0,202,0,204,0,218,0,246,0,251,0,255,0,72,1,79,1, +90,1,128,1,135,1,144,1,177,1,210,1,16,2,21,2,102,2,107,2,112, +2,133,2,30,3,51,3,104,3,173,3,242,3,132,4,24,5,35,5,118,5, +0,0,147,7,0,0,3,1,5,105,110,115,112,48,71,35,37,109,105,110,45, +115,116,120,29,11,11,11,65,97,110,100,66,99,111,110,100,68,100,101,102,105, +110,101,65,108,101,116,66,108,101,116,42,73,108,101,116,42,45,118,97,108,117, +101,115,68,108,101,116,114,101,99,64,111,114,74,112,97,114,97,109,101,116,101, +114,105,122,101,68,117,110,108,101,115,115,66,119,104,101,110,70,104,101,114,101, +45,115,116,120,67,113,117,111,116,101,29,94,2,16,70,35,37,107,101,114,110, +101,108,11,29,94,2,16,70,35,37,112,97,114,97,109,122,11,64,105,102,67, +98,101,103,105,110,72,108,101,116,45,118,97,108,117,101,115,63,120,75,108,101, +116,114,101,99,45,118,97,108,117,101,115,68,108,97,109,98,100,97,1,20,112, +97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,63,118, +75,100,101,102,105,110,101,45,118,97,108,117,101,115,38,28,16,3,93,16,2, +29,11,11,11,2,3,2,29,93,143,16,5,39,2,31,40,2,34,2,2,39, +38,29,93,2,30,36,30,0,39,36,31,1,145,40,143,2,32,16,4,2,17, +39,39,2,1,143,2,32,16,4,2,18,39,39,2,1,16,22,2,4,2,33, +2,5,2,33,2,6,2,33,2,7,2,33,2,8,2,33,2,9,2,33,2, +10,2,33,2,11,2,33,2,12,2,33,2,13,2,33,2,14,2,33,38,32, +143,2,31,2,29,38,33,93,143,2,32,143,2,1,2,3,36,34,2,144,40, +143,2,35,16,4,2,17,40,39,2,1,16,2,2,15,93,143,2,35,147,2, +1,2,3,40,2,15,143,2,3,40,2,15,38,35,143,2,34,2,29,18,143, +66,104,101,114,101,2,28,27,248,22,164,4,195,249,22,157,4,80,143,42,39, +251,22,90,2,19,248,22,102,199,12,249,22,80,2,20,248,22,104,201,27,248, +22,164,4,195,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,102,199, +249,22,80,2,20,248,22,104,201,12,27,248,22,82,248,22,164,4,196,28,248, +22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,163,20, +193,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,163,20,199,249,22, +80,2,4,248,22,164,20,201,11,18,143,10,2,28,27,248,22,82,248,22,164, +4,196,28,248,22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194, +248,22,163,20,193,249,22,157,4,80,143,42,39,250,22,90,2,21,248,22,90, +249,22,90,248,22,90,2,22,248,22,163,20,201,251,22,90,2,19,2,22,2, +22,249,22,80,2,11,248,22,164,20,204,18,143,11,2,28,248,22,164,4,193, +27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22,164,20,195, +27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80,143,42,39,28,248, +22,64,248,22,158,4,248,22,81,23,198,2,27,249,22,2,32,0,88,148,8, +36,40,46,11,9,222,33,43,248,22,164,4,248,22,102,23,200,2,250,22,90, +2,23,248,22,90,249,22,90,248,22,90,248,22,163,20,23,204,2,250,22,91, +2,24,249,22,2,22,81,23,204,2,248,22,104,23,206,2,249,22,80,248,22, +163,20,23,202,1,249,22,2,22,102,23,200,1,250,22,91,2,21,249,22,2, +32,0,88,148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,163,20, +201,248,22,164,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81, +196,248,22,164,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4, +80,143,42,39,250,22,91,2,23,249,22,2,32,0,88,148,8,36,40,50,11, +9,222,33,46,248,22,164,4,248,22,81,201,248,22,164,20,198,27,248,22,82, +248,22,164,4,196,27,248,22,164,4,248,22,81,195,249,22,157,4,80,143,43, +39,28,248,22,88,195,250,22,91,2,21,9,248,22,164,20,199,250,22,90,2, +7,248,22,90,248,22,81,199,250,22,91,2,8,248,22,164,20,201,248,22,164, +20,202,27,248,22,82,248,22,164,4,196,27,248,22,164,4,248,22,81,195,249, +22,157,4,80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,164, +20,199,250,22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22, +164,20,201,248,22,164,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249, +22,1,22,94,249,22,2,22,164,4,248,22,164,4,248,22,81,199,248,22,185, +4,249,22,157,4,80,143,44,39,251,22,90,1,22,119,105,116,104,45,99,111, +110,116,105,110,117,97,116,105,111,110,45,109,97,114,107,2,25,250,22,91,1, +23,101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116, +105,111,110,21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109, +97,114,107,45,115,101,116,45,102,105,114,115,116,11,2,25,202,250,22,91,2, +21,9,248,22,164,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193, +20,14,144,40,39,40,249,22,157,4,80,143,42,39,27,248,22,164,4,248,22, +81,197,28,249,22,169,9,64,61,62,248,22,158,4,248,22,102,196,250,22,90, +2,21,248,22,90,249,22,90,21,93,2,26,248,22,163,20,199,250,22,91,2, +5,249,22,90,2,26,249,22,90,248,22,111,203,2,26,248,22,164,20,202,251, +22,90,2,19,28,249,22,169,9,248,22,158,4,248,22,163,20,200,66,101,108, +115,101,10,248,22,163,20,197,250,22,91,2,21,9,248,22,164,20,200,249,22, +80,2,5,248,22,164,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248, +22,82,248,22,164,4,196,249,22,157,4,80,143,42,39,28,248,22,64,248,22, +158,4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,163,20,199,248,22, +102,198,27,248,22,158,4,248,22,163,20,197,250,22,90,2,27,248,22,90,248, +22,81,197,250,22,91,2,24,248,22,164,20,199,248,22,164,20,202,144,39,20, +121,145,2,1,39,16,1,11,16,0,20,27,15,61,9,2,2,2,2,2,3, +11,11,11,11,9,9,11,11,11,10,39,80,143,39,39,20,121,145,2,1,39, +16,0,16,0,41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4,2, +5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,16,11, +11,11,11,11,11,11,11,11,11,11,11,16,11,2,4,2,5,2,6,2,7, +2,8,2,9,2,10,2,11,2,12,2,13,2,14,39,50,40,16,0,39,16, +1,2,15,40,11,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0, +16,0,16,0,39,39,16,12,16,5,11,20,15,16,2,20,14,144,39,39,40, +80,143,39,39,39,20,121,145,2,1,39,16,1,2,15,16,1,33,36,10,16, +5,2,13,88,148,8,36,40,56,40,9,223,0,33,37,39,20,121,145,2,1, +39,16,1,2,15,16,0,11,16,5,2,14,88,148,8,36,40,56,40,9,223, +0,33,38,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,4, +88,148,8,36,40,56,42,9,223,0,33,39,39,20,121,145,2,1,39,16,1, +2,15,16,1,33,40,11,16,5,2,11,88,148,8,36,40,59,42,9,223,0, +33,41,39,20,121,145,2,1,39,16,1,2,15,16,1,33,42,11,16,5,2, +7,88,148,8,36,40,61,40,9,223,0,33,45,39,20,121,145,2,1,39,16, +1,2,15,16,0,11,16,5,2,10,88,148,8,36,40,56,40,9,223,0,33, +47,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,8,88,148, +8,36,40,57,40,9,223,0,33,48,39,20,121,145,2,1,39,16,1,2,15, +16,0,11,16,5,2,9,88,148,8,36,40,57,40,9,223,0,33,49,39,20, +121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,12,88,148,8,36,40, +59,40,9,223,0,33,50,39,20,121,145,2,1,39,16,1,2,15,16,0,11, +16,5,2,5,88,148,8,36,40,61,42,9,223,0,33,51,39,20,121,145,2, +1,39,16,1,2,15,16,1,33,52,11,16,5,2,6,88,148,8,36,40,57, +40,9,223,0,33,53,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16, +0,94,2,17,2,18,93,2,17,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 2092); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,1,0,0,8,0, -16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,178,0,193, -0,211,0,223,0,239,0,253,0,19,1,39,1,73,1,90,1,107,1,130,1, -145,1,184,1,202,1,233,1,245,1,6,2,18,2,33,2,57,2,89,2,118, -2,134,2,152,2,172,2,193,2,211,2,242,2,0,3,17,3,61,3,69,3, -74,3,118,3,125,3,135,3,150,3,159,3,164,3,166,3,199,3,223,3,244, -3,1,4,11,4,20,4,31,4,49,4,62,4,72,4,82,4,88,4,93,4, -105,4,108,4,112,4,117,4,160,4,173,4,176,4,200,4,239,4,246,4,3, -5,25,5,36,5,66,5,89,5,97,5,121,5,142,5,86,6,116,6,197,9, -220,9,237,9,161,11,8,12,22,12,226,12,202,14,211,14,220,14,234,14,244, -14,5,16,108,16,221,16,38,17,111,17,215,17,244,17,59,18,197,18,12,19, -225,19,87,20,100,20,218,20,231,20,70,21,137,21,150,21,161,21,57,22,175, -22,219,22,74,23,152,25,176,25,38,26,120,27,127,27,179,27,192,27,182,28, -198,28,53,29,212,29,219,29,96,31,173,31,190,31,90,32,110,32,170,32,177, -32,37,33,91,33,110,33,61,34,77,34,38,35,27,36,64,36,73,36,150,37, -251,39,11,40,78,40,99,40,119,40,139,40,196,40,156,43,122,44,138,44,109, -45,167,45,200,45,76,46,235,46,251,46,92,47,109,47,187,49,238,51,254,51, -228,53,160,54,162,54,189,54,205,54,221,54,62,55,129,56,61,57,77,57,86, -57,93,57,159,58,225,59,87,60,133,63,7,64,139,64,84,66,34,67,76,67, -184,67,0,0,131,75,0,0,3,1,5,105,110,115,112,48,69,35,37,117,116, -105,108,115,74,112,97,116,104,45,115,116,114,105,110,103,63,66,98,115,98,115, -78,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116,104,73,114,101,114, -111,111,116,45,112,97,116,104,1,20,102,105,110,100,45,101,120,101,99,117,116, -97,98,108,101,45,112,97,116,104,1,27,112,97,116,104,45,108,105,115,116,45, -115,116,114,105,110,103,45,62,112,97,116,104,45,108,105,115,116,1,42,99,97, -108,108,45,119,105,116,104,45,100,101,102,97,117,108,116,45,114,101,97,100,105, -110,103,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,67,113, -117,111,116,101,29,94,2,10,70,35,37,112,97,114,97,109,122,11,76,45,99, -104,101,99,107,45,114,101,108,112,97,116,104,79,45,99,104,101,99,107,45,99, -111,108,108,101,99,116,105,111,110,73,45,99,104,101,99,107,45,102,97,105,108, -77,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,75,102,105,110,100, -45,99,111,108,45,102,105,108,101,1,20,99,111,108,108,101,99,116,105,111,110, -45,102,105,108,101,45,112,97,116,104,1,18,102,105,110,100,45,109,97,105,110, -45,99,111,108,108,101,99,116,115,1,32,101,120,101,45,114,101,108,97,116,105, -118,101,45,112,97,116,104,45,62,99,111,109,112,108,101,116,101,45,112,97,116, -104,78,102,105,110,100,45,109,97,105,110,45,99,111,110,102,105,103,78,103,101, -116,45,99,111,110,102,105,103,45,116,97,98,108,101,1,21,103,101,116,45,105, -110,115,116,97,108,108,97,116,105,111,110,45,110,97,109,101,76,99,111,101,114, -99,101,45,116,111,45,112,97,116,104,1,37,99,111,108,108,101,99,116,115,45, -114,101,108,97,116,105,118,101,45,112,97,116,104,45,62,99,111,109,112,108,101, -116,101,45,112,97,116,104,79,97,100,100,45,99,111,110,102,105,103,45,115,101, -97,114,99,104,1,29,102,105,110,100,45,108,105,98,114,97,114,121,45,99,111, -108,108,101,99,116,105,111,110,45,108,105,110,107,115,73,108,105,110,107,115,45, -99,97,99,104,101,78,115,116,97,109,112,45,112,114,111,109,112,116,45,116,97, -103,73,102,105,108,101,45,62,115,116,97,109,112,76,110,111,45,102,105,108,101, -45,115,116,97,109,112,63,1,22,103,101,116,45,108,105,110,107,101,100,45,99, -111,108,108,101,99,116,105,111,110,115,1,30,110,111,114,109,97,108,105,122,101, -45,99,111,108,108,101,99,116,105,111,110,45,114,101,102,101,114,101,110,99,101, -1,27,102,105,108,101,45,101,120,105,115,116,115,63,47,109,97,121,98,101,45, -99,111,109,112,105,108,101,100,77,112,97,116,104,45,97,100,100,45,115,117,102, -102,105,120,79,99,104,101,99,107,45,115,117,102,102,105,120,45,99,97,108,108, -1,18,112,97,116,104,45,97,100,106,117,115,116,45,115,117,102,102,105,120,1, -19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102,105,120,79, -108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,1,29,102,105, -110,100,45,108,105,98,114,97,114,121,45,99,111,108,108,101,99,116,105,111,110, -45,112,97,116,104,115,75,101,109,98,101,100,100,101,100,45,108,111,97,100,78, -110,111,114,109,97,108,45,112,97,116,104,45,99,97,115,101,6,41,41,40,111, -114,47,99,32,112,97,116,104,45,102,111,114,45,115,111,109,101,45,115,121,115, -116,101,109,63,32,112,97,116,104,45,115,116,114,105,110,103,63,41,69,119,105, -110,100,111,119,115,6,2,2,92,49,6,41,41,40,111,114,47,99,32,112,97, -116,104,45,115,116,114,105,110,103,63,32,112,97,116,104,45,102,111,114,45,115, -111,109,101,45,115,121,115,116,101,109,63,41,6,4,4,112,97,116,104,5,8, -92,92,63,92,82,69,76,92,6,12,12,112,97,116,104,45,115,116,114,105,110, -103,63,70,114,101,108,97,116,105,118,101,66,108,111,111,112,5,0,6,30,30, -40,112,114,111,99,101,100,117,114,101,45,97,114,105,116,121,45,105,110,99,108, -117,100,101,115,47,99,32,48,41,6,21,21,105,110,118,97,108,105,100,32,114, -101,108,97,116,105,118,101,32,112,97,116,104,6,18,18,40,97,110,121,47,99, -32,46,32,45,62,32,46,32,97,110,121,41,74,99,111,108,108,101,99,116,115, -45,100,105,114,71,101,120,101,99,45,102,105,108,101,70,111,114,105,103,45,100, -105,114,72,99,111,110,102,105,103,45,100,105,114,79,105,110,115,116,97,108,108, -97,116,105,111,110,45,110,97,109,101,6,10,10,108,105,110,107,115,46,114,107, -116,100,71,97,100,100,111,110,45,100,105,114,71,102,115,45,99,104,97,110,103, -101,67,101,114,114,111,114,66,114,111,111,116,73,115,116,97,116,105,99,45,114, -111,111,116,6,0,0,6,1,1,47,5,3,46,122,111,6,40,40,114,101,109, -111,118,105,110,103,32,115,117,102,102,105,120,32,109,97,107,101,115,32,112,97, -116,104,32,101,108,101,109,101,110,116,32,101,109,112,116,121,6,10,10,103,105, -118,101,110,32,112,97,116,104,5,1,95,6,21,21,40,111,114,47,99,32,115, -116,114,105,110,103,63,32,98,121,116,101,115,63,41,6,36,36,99,97,110,110, -111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111,32,97,32, -114,111,111,116,32,112,97,116,104,58,32,68,102,105,110,105,115,104,5,11,80, -76,84,67,79,76,76,69,67,84,83,1,20,99,111,108,108,101,99,116,115,45, -115,101,97,114,99,104,45,100,105,114,115,6,8,8,99,111,108,108,101,99,116, -115,27,248,22,174,15,194,28,192,192,28,248,22,153,7,194,27,248,22,133,16, -195,28,192,192,248,22,134,16,195,11,0,21,35,114,120,34,94,91,92,92,93, -91,92,92,93,91,63,93,91,92,92,93,34,0,6,35,114,120,34,47,34,0, -22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91,47,92,92,93,42, -36,34,0,19,35,114,120,34,91,32,46,93,43,40,91,47,92,92,93,42,41, -36,34,86,94,28,28,248,22,175,15,23,195,2,10,28,248,22,174,15,23,195, -2,10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22, -134,16,23,195,2,11,12,250,22,181,11,2,41,2,42,23,197,2,28,28,248, -22,175,15,23,195,2,249,22,169,9,248,22,176,15,23,197,2,2,43,249,22, -169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,196,2,23,195,2,248, -22,165,8,248,22,179,15,23,197,2,28,249,22,171,16,2,79,23,195,2,28, -248,22,153,7,195,248,22,182,15,195,194,27,248,22,128,8,23,195,1,249,22, -183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171,16,2,81,23,201, -2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80,144,47,40,41,2, -43,28,248,22,153,7,194,248,22,182,15,194,193,0,28,35,114,120,34,94,92, -92,92,92,92,92,92,92,91,63,93,92,92,92,92,85,78,67,92,92,92,92, -34,86,95,28,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195, -2,28,248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,10,248,22, -175,15,23,195,2,12,252,22,181,11,2,6,2,45,39,23,199,2,23,200,2, -28,28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248, -22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,10,248,22,175,15,23, -196,2,12,252,22,181,11,2,6,2,45,40,23,199,2,23,200,2,27,28,248, -22,175,15,23,196,2,248,22,176,15,23,196,2,247,22,177,15,86,95,28,28, -248,22,135,16,23,196,2,10,249,22,169,9,247,22,177,15,23,195,2,12,253, -22,183,11,2,6,6,54,54,112,97,116,104,32,105,115,32,110,111,116,32,99, -111,109,112,108,101,116,101,32,97,110,100,32,110,111,116,32,116,104,101,32,112, -108,97,116,102,111,114,109,39,115,32,99,111,110,118,101,110,116,105,111,110,2, -46,23,201,2,6,24,24,112,108,97,116,102,111,114,109,32,99,111,110,118,101, -110,116,105,111,110,32,116,121,112,101,247,22,177,15,28,249,22,169,9,28,248, -22,175,15,23,199,2,248,22,176,15,23,199,2,247,22,177,15,23,195,2,12, -253,22,183,11,2,6,6,37,37,103,105,118,101,110,32,112,97,116,104,115,32, -117,115,101,32,100,105,102,102,101,114,101,110,116,32,99,111,110,118,101,110,116, -105,111,110,115,2,46,23,201,2,6,9,9,114,111,111,116,32,112,97,116,104, -23,202,2,27,27,248,22,139,16,28,248,22,135,16,23,199,2,23,198,1,248, -22,136,16,23,199,1,86,94,28,28,248,22,175,15,23,194,2,10,28,248,22, -174,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,133,16,23,194, -2,10,248,22,134,16,23,194,2,11,12,250,22,181,11,2,41,2,42,23,196, -2,28,28,248,22,175,15,23,194,2,249,22,169,9,248,22,176,15,23,196,2, -2,43,249,22,169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,195,2, -23,194,2,248,22,165,8,248,22,179,15,23,196,2,28,249,22,171,16,2,79, -23,195,2,28,248,22,153,7,194,248,22,182,15,194,193,27,248,22,128,8,23, -195,1,249,22,183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171,16, -2,81,23,201,2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80,144, -50,40,41,2,43,28,248,22,153,7,193,248,22,182,15,193,192,27,248,22,179, -15,23,195,2,28,249,22,169,9,23,197,2,66,117,110,105,120,28,249,22,150, -8,194,5,1,47,28,248,22,175,15,198,197,248,22,182,15,198,249,22,128,16, -199,249,22,183,15,249,22,153,8,248,22,179,15,200,40,198,28,249,22,169,9, -23,197,2,2,43,249,22,128,16,23,200,1,249,22,183,15,28,249,22,171,16, -0,27,35,114,120,34,94,92,92,92,92,92,92,92,92,91,63,93,92,92,92, -92,91,97,45,122,93,58,34,23,199,2,251,22,154,8,2,47,250,22,153,8, -203,43,44,5,1,92,249,22,153,8,202,45,28,249,22,171,16,2,84,23,199, -2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,2,84,23, -199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,0,14, -35,114,120,34,94,92,92,92,92,92,92,92,92,34,23,199,2,249,22,154,8, -5,4,85,78,67,92,249,22,153,8,200,41,28,249,22,171,16,0,12,35,114, -120,34,94,91,97,45,122,93,58,34,198,249,22,154,8,250,22,153,8,201,39, -40,249,22,153,8,200,41,12,198,12,32,86,88,148,8,36,42,56,11,72,102, -111,117,110,100,45,101,120,101,99,222,33,89,32,87,88,148,8,36,43,61,11, -66,110,101,120,116,222,33,88,27,248,22,137,16,23,196,2,28,249,22,171,9, -23,195,2,23,197,1,11,28,248,22,133,16,23,194,2,27,249,22,128,16,23, -197,1,23,196,1,28,23,197,2,90,144,42,11,89,146,42,39,11,248,22,131, -16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,2,27,248,22,137, -16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28,248,22,133,16, -23,194,2,250,2,86,23,205,2,23,206,2,249,22,128,16,23,200,2,23,198, -1,250,2,86,23,205,2,23,206,2,23,196,1,11,28,23,193,2,192,86,94, -23,193,1,27,28,248,22,174,15,23,196,2,27,249,22,128,16,23,198,2,23, -205,2,28,28,248,22,187,15,193,10,248,22,186,15,193,192,11,11,28,23,193, -2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,137,16,23,200,2,28, -249,22,171,9,194,23,201,1,11,28,248,22,133,16,193,250,2,86,205,206,249, -22,128,16,200,197,250,2,86,205,206,195,192,86,94,23,194,1,28,23,196,2, -90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,2,86,95,23,195,1, -23,194,1,27,28,23,201,2,27,248,22,137,16,23,199,2,28,249,22,171,9, -23,195,2,23,200,2,11,28,248,22,133,16,23,194,2,250,2,86,23,204,2, -23,205,2,249,22,128,16,23,200,2,23,198,1,250,2,86,23,204,2,23,205, -2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,174,15, -23,196,2,27,249,22,128,16,23,198,2,23,204,2,28,28,248,22,187,15,193, -10,248,22,186,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28,23, -202,2,11,27,248,22,137,16,23,200,2,28,249,22,171,9,194,23,201,1,11, -28,248,22,133,16,193,250,2,86,204,205,249,22,128,16,200,197,250,2,86,204, -205,195,192,28,23,193,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23, -199,2,86,95,23,195,1,23,194,1,27,28,23,198,2,251,2,87,23,198,2, -23,203,2,23,201,2,23,202,2,11,28,23,193,2,192,86,94,23,193,1,27, -28,248,22,174,15,195,27,249,22,128,16,197,200,28,28,248,22,187,15,193,10, -248,22,186,15,193,192,11,11,28,192,192,28,198,11,251,2,87,198,203,201,202, -194,32,90,88,148,8,36,43,60,11,2,50,222,33,91,28,248,22,88,23,197, -2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,201,2,23,196,2,28, -248,22,186,15,23,194,2,250,2,86,197,198,195,86,94,23,193,1,27,248,22, -163,20,23,199,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22,136, -16,248,22,81,23,198,2,23,198,2,28,248,22,186,15,23,194,2,250,2,86, -199,200,195,86,94,23,193,1,27,248,22,163,20,23,196,1,28,248,22,88,23, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,1,0,0,8, +0,16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,178,0, +193,0,211,0,223,0,239,0,253,0,19,1,39,1,73,1,90,1,107,1,130, +1,145,1,184,1,202,1,233,1,245,1,6,2,18,2,33,2,57,2,89,2, +118,2,134,2,152,2,172,2,193,2,211,2,242,2,0,3,17,3,61,3,69, +3,74,3,118,3,125,3,135,3,150,3,159,3,164,3,166,3,199,3,223,3, +244,3,1,4,11,4,20,4,31,4,49,4,62,4,72,4,82,4,88,4,93, +4,105,4,108,4,112,4,117,4,160,4,173,4,176,4,200,4,239,4,246,4, +3,5,25,5,36,5,66,5,89,5,97,5,121,5,142,5,86,6,116,6,197, +9,220,9,237,9,161,11,8,12,22,12,226,12,202,14,211,14,220,14,234,14, +244,14,5,16,108,16,221,16,38,17,111,17,215,17,244,17,59,18,197,18,12, +19,225,19,87,20,100,20,218,20,231,20,70,21,137,21,150,21,161,21,57,22, +175,22,219,22,74,23,152,25,176,25,38,26,120,27,127,27,179,27,192,27,182, +28,198,28,53,29,212,29,219,29,96,31,173,31,190,31,90,32,110,32,170,32, +177,32,37,33,91,33,110,33,61,34,77,34,38,35,27,36,64,36,73,36,150, +37,251,39,11,40,78,40,99,40,119,40,139,40,196,40,156,43,122,44,138,44, +109,45,167,45,200,45,76,46,235,46,251,46,92,47,109,47,187,49,238,51,254, +51,228,53,160,54,162,54,189,54,205,54,221,54,62,55,129,56,61,57,77,57, +86,57,93,57,159,58,225,59,87,60,133,63,7,64,139,64,84,66,34,67,76, +67,184,67,0,0,131,75,0,0,3,1,5,105,110,115,112,48,69,35,37,117, +116,105,108,115,74,112,97,116,104,45,115,116,114,105,110,103,63,66,98,115,98, +115,78,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116,104,73,114,101, +114,111,111,116,45,112,97,116,104,1,20,102,105,110,100,45,101,120,101,99,117, +116,97,98,108,101,45,112,97,116,104,1,27,112,97,116,104,45,108,105,115,116, +45,115,116,114,105,110,103,45,62,112,97,116,104,45,108,105,115,116,1,42,99, +97,108,108,45,119,105,116,104,45,100,101,102,97,117,108,116,45,114,101,97,100, +105,110,103,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,67, +113,117,111,116,101,29,94,2,10,70,35,37,112,97,114,97,109,122,11,76,45, +99,104,101,99,107,45,114,101,108,112,97,116,104,79,45,99,104,101,99,107,45, +99,111,108,108,101,99,116,105,111,110,73,45,99,104,101,99,107,45,102,97,105, +108,77,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,75,102,105,110, +100,45,99,111,108,45,102,105,108,101,1,20,99,111,108,108,101,99,116,105,111, +110,45,102,105,108,101,45,112,97,116,104,1,18,102,105,110,100,45,109,97,105, +110,45,99,111,108,108,101,99,116,115,1,32,101,120,101,45,114,101,108,97,116, +105,118,101,45,112,97,116,104,45,62,99,111,109,112,108,101,116,101,45,112,97, +116,104,78,102,105,110,100,45,109,97,105,110,45,99,111,110,102,105,103,78,103, +101,116,45,99,111,110,102,105,103,45,116,97,98,108,101,1,21,103,101,116,45, +105,110,115,116,97,108,108,97,116,105,111,110,45,110,97,109,101,76,99,111,101, +114,99,101,45,116,111,45,112,97,116,104,1,37,99,111,108,108,101,99,116,115, +45,114,101,108,97,116,105,118,101,45,112,97,116,104,45,62,99,111,109,112,108, +101,116,101,45,112,97,116,104,79,97,100,100,45,99,111,110,102,105,103,45,115, +101,97,114,99,104,1,29,102,105,110,100,45,108,105,98,114,97,114,121,45,99, +111,108,108,101,99,116,105,111,110,45,108,105,110,107,115,73,108,105,110,107,115, +45,99,97,99,104,101,78,115,116,97,109,112,45,112,114,111,109,112,116,45,116, +97,103,73,102,105,108,101,45,62,115,116,97,109,112,76,110,111,45,102,105,108, +101,45,115,116,97,109,112,63,1,22,103,101,116,45,108,105,110,107,101,100,45, +99,111,108,108,101,99,116,105,111,110,115,1,30,110,111,114,109,97,108,105,122, +101,45,99,111,108,108,101,99,116,105,111,110,45,114,101,102,101,114,101,110,99, +101,1,27,102,105,108,101,45,101,120,105,115,116,115,63,47,109,97,121,98,101, +45,99,111,109,112,105,108,101,100,77,112,97,116,104,45,97,100,100,45,115,117, +102,102,105,120,79,99,104,101,99,107,45,115,117,102,102,105,120,45,99,97,108, +108,1,18,112,97,116,104,45,97,100,106,117,115,116,45,115,117,102,102,105,120, +1,19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102,105,120, +79,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,1,29,102, +105,110,100,45,108,105,98,114,97,114,121,45,99,111,108,108,101,99,116,105,111, +110,45,112,97,116,104,115,75,101,109,98,101,100,100,101,100,45,108,111,97,100, +78,110,111,114,109,97,108,45,112,97,116,104,45,99,97,115,101,6,41,41,40, +111,114,47,99,32,112,97,116,104,45,102,111,114,45,115,111,109,101,45,115,121, +115,116,101,109,63,32,112,97,116,104,45,115,116,114,105,110,103,63,41,69,119, +105,110,100,111,119,115,6,2,2,92,49,6,41,41,40,111,114,47,99,32,112, +97,116,104,45,115,116,114,105,110,103,63,32,112,97,116,104,45,102,111,114,45, +115,111,109,101,45,115,121,115,116,101,109,63,41,6,4,4,112,97,116,104,5, +8,92,92,63,92,82,69,76,92,6,12,12,112,97,116,104,45,115,116,114,105, +110,103,63,70,114,101,108,97,116,105,118,101,66,108,111,111,112,5,0,6,30, +30,40,112,114,111,99,101,100,117,114,101,45,97,114,105,116,121,45,105,110,99, +108,117,100,101,115,47,99,32,48,41,6,21,21,105,110,118,97,108,105,100,32, +114,101,108,97,116,105,118,101,32,112,97,116,104,6,18,18,40,97,110,121,47, +99,32,46,32,45,62,32,46,32,97,110,121,41,74,99,111,108,108,101,99,116, +115,45,100,105,114,71,101,120,101,99,45,102,105,108,101,70,111,114,105,103,45, +100,105,114,72,99,111,110,102,105,103,45,100,105,114,79,105,110,115,116,97,108, +108,97,116,105,111,110,45,110,97,109,101,6,10,10,108,105,110,107,115,46,114, +107,116,100,71,97,100,100,111,110,45,100,105,114,71,102,115,45,99,104,97,110, +103,101,67,101,114,114,111,114,66,114,111,111,116,73,115,116,97,116,105,99,45, +114,111,111,116,6,0,0,6,1,1,47,5,3,46,122,111,6,40,40,114,101, +109,111,118,105,110,103,32,115,117,102,102,105,120,32,109,97,107,101,115,32,112, +97,116,104,32,101,108,101,109,101,110,116,32,101,109,112,116,121,6,10,10,103, +105,118,101,110,32,112,97,116,104,5,1,95,6,21,21,40,111,114,47,99,32, +115,116,114,105,110,103,63,32,98,121,116,101,115,63,41,6,36,36,99,97,110, +110,111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111,32,97, +32,114,111,111,116,32,112,97,116,104,58,32,68,102,105,110,105,115,104,5,11, +80,76,84,67,79,76,76,69,67,84,83,1,20,99,111,108,108,101,99,116,115, +45,115,101,97,114,99,104,45,100,105,114,115,6,8,8,99,111,108,108,101,99, +116,115,27,248,22,174,15,194,28,192,192,28,248,22,153,7,194,27,248,22,133, +16,195,28,192,192,248,22,134,16,195,11,0,21,35,114,120,34,94,91,92,92, +93,91,92,92,93,91,63,93,91,92,92,93,34,0,6,35,114,120,34,47,34, +0,22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91,47,92,92,93, +42,36,34,0,19,35,114,120,34,91,32,46,93,43,40,91,47,92,92,93,42, +41,36,34,86,94,28,28,248,22,175,15,23,195,2,10,28,248,22,174,15,23, +195,2,10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248, +22,134,16,23,195,2,11,12,250,22,181,11,2,41,2,42,23,197,2,28,28, +248,22,175,15,23,195,2,249,22,169,9,248,22,176,15,23,197,2,2,43,249, +22,169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,196,2,23,195,2, +248,22,165,8,248,22,179,15,23,197,2,28,249,22,171,16,2,79,23,195,2, +28,248,22,153,7,195,248,22,182,15,195,194,27,248,22,128,8,23,195,1,249, +22,183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171,16,2,81,23, +201,2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80,144,47,40,41, +2,43,28,248,22,153,7,194,248,22,182,15,194,193,0,28,35,114,120,34,94, +92,92,92,92,92,92,92,92,91,63,93,92,92,92,92,85,78,67,92,92,92, +92,34,86,95,28,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23, +195,2,28,248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,10,248, +22,175,15,23,195,2,12,252,22,181,11,2,6,2,45,39,23,199,2,23,200, +2,28,28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28, +248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,10,248,22,175,15, +23,196,2,12,252,22,181,11,2,6,2,45,40,23,199,2,23,200,2,27,28, +248,22,175,15,23,196,2,248,22,176,15,23,196,2,247,22,177,15,86,95,28, +28,248,22,135,16,23,196,2,10,249,22,169,9,247,22,177,15,23,195,2,12, +253,22,183,11,2,6,6,54,54,112,97,116,104,32,105,115,32,110,111,116,32, +99,111,109,112,108,101,116,101,32,97,110,100,32,110,111,116,32,116,104,101,32, +112,108,97,116,102,111,114,109,39,115,32,99,111,110,118,101,110,116,105,111,110, +2,46,23,201,2,6,24,24,112,108,97,116,102,111,114,109,32,99,111,110,118, +101,110,116,105,111,110,32,116,121,112,101,247,22,177,15,28,249,22,169,9,28, +248,22,175,15,23,199,2,248,22,176,15,23,199,2,247,22,177,15,23,195,2, +12,253,22,183,11,2,6,6,37,37,103,105,118,101,110,32,112,97,116,104,115, +32,117,115,101,32,100,105,102,102,101,114,101,110,116,32,99,111,110,118,101,110, +116,105,111,110,115,2,46,23,201,2,6,9,9,114,111,111,116,32,112,97,116, +104,23,202,2,27,27,248,22,139,16,28,248,22,135,16,23,199,2,23,198,1, +248,22,136,16,23,199,1,86,94,28,28,248,22,175,15,23,194,2,10,28,248, +22,174,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,133,16,23, +194,2,10,248,22,134,16,23,194,2,11,12,250,22,181,11,2,41,2,42,23, +196,2,28,28,248,22,175,15,23,194,2,249,22,169,9,248,22,176,15,23,196, +2,2,43,249,22,169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,195, +2,23,194,2,248,22,165,8,248,22,179,15,23,196,2,28,249,22,171,16,2, +79,23,195,2,28,248,22,153,7,194,248,22,182,15,194,193,27,248,22,128,8, +23,195,1,249,22,183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171, +16,2,81,23,201,2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80, +144,50,40,41,2,43,28,248,22,153,7,193,248,22,182,15,193,192,27,248,22, +179,15,23,195,2,28,249,22,169,9,23,197,2,66,117,110,105,120,28,249,22, +150,8,194,5,1,47,28,248,22,175,15,198,197,248,22,182,15,198,249,22,128, +16,199,249,22,183,15,249,22,153,8,248,22,179,15,200,40,198,28,249,22,169, +9,23,197,2,2,43,249,22,128,16,23,200,1,249,22,183,15,28,249,22,171, +16,0,27,35,114,120,34,94,92,92,92,92,92,92,92,92,91,63,93,92,92, +92,92,91,97,45,122,93,58,34,23,199,2,251,22,154,8,2,47,250,22,153, +8,203,43,44,5,1,92,249,22,153,8,202,45,28,249,22,171,16,2,84,23, +199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,2,84, +23,199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,0, +14,35,114,120,34,94,92,92,92,92,92,92,92,92,34,23,199,2,249,22,154, +8,5,4,85,78,67,92,249,22,153,8,200,41,28,249,22,171,16,0,12,35, +114,120,34,94,91,97,45,122,93,58,34,198,249,22,154,8,250,22,153,8,201, +39,40,249,22,153,8,200,41,12,198,12,32,86,88,148,8,36,42,56,11,72, +102,111,117,110,100,45,101,120,101,99,222,33,89,32,87,88,148,8,36,43,61, +11,66,110,101,120,116,222,33,88,27,248,22,137,16,23,196,2,28,249,22,171, +9,23,195,2,23,197,1,11,28,248,22,133,16,23,194,2,27,249,22,128,16, +23,197,1,23,196,1,28,23,197,2,90,144,42,11,89,146,42,39,11,248,22, +131,16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,2,27,248,22, +137,16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28,248,22,133, +16,23,194,2,250,2,86,23,205,2,23,206,2,249,22,128,16,23,200,2,23, +198,1,250,2,86,23,205,2,23,206,2,23,196,1,11,28,23,193,2,192,86, +94,23,193,1,27,28,248,22,174,15,23,196,2,27,249,22,128,16,23,198,2, +23,205,2,28,28,248,22,187,15,193,10,248,22,186,15,193,192,11,11,28,23, +193,2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,137,16,23,200,2, +28,249,22,171,9,194,23,201,1,11,28,248,22,133,16,193,250,2,86,205,206, +249,22,128,16,200,197,250,2,86,205,206,195,192,86,94,23,194,1,28,23,196, +2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,2,86,95,23,195, +1,23,194,1,27,28,23,201,2,27,248,22,137,16,23,199,2,28,249,22,171, +9,23,195,2,23,200,2,11,28,248,22,133,16,23,194,2,250,2,86,23,204, +2,23,205,2,249,22,128,16,23,200,2,23,198,1,250,2,86,23,204,2,23, +205,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,174, +15,23,196,2,27,249,22,128,16,23,198,2,23,204,2,28,28,248,22,187,15, +193,10,248,22,186,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28, +23,202,2,11,27,248,22,137,16,23,200,2,28,249,22,171,9,194,23,201,1, +11,28,248,22,133,16,193,250,2,86,204,205,249,22,128,16,200,197,250,2,86, +204,205,195,192,28,23,193,2,90,144,42,11,89,146,42,39,11,248,22,131,16, +23,199,2,86,95,23,195,1,23,194,1,27,28,23,198,2,251,2,87,23,198, +2,23,203,2,23,201,2,23,202,2,11,28,23,193,2,192,86,94,23,193,1, +27,28,248,22,174,15,195,27,249,22,128,16,197,200,28,28,248,22,187,15,193, +10,248,22,186,15,193,192,11,11,28,192,192,28,198,11,251,2,87,198,203,201, +202,194,32,90,88,148,8,36,43,60,11,2,50,222,33,91,28,248,22,88,23, +197,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,201,2,23,196,2, +28,248,22,186,15,23,194,2,250,2,86,197,198,195,86,94,23,193,1,27,248, +22,164,20,23,199,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, +136,16,248,22,81,23,198,2,23,198,2,28,248,22,186,15,23,194,2,250,2, +86,199,200,195,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248,22,88, +23,194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,200, +2,28,248,22,186,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27, +248,22,164,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248, +22,136,16,248,22,81,197,201,28,248,22,186,15,193,250,2,86,203,204,195,251, +2,90,203,204,205,248,22,164,20,198,86,95,28,28,248,22,174,15,23,195,2, +10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134, +16,23,195,2,11,12,250,22,181,11,2,7,2,48,23,197,2,28,28,23,195, +2,28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248, +22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,248,22,133,16,23,196, +2,11,10,12,250,22,181,11,2,7,6,45,45,40,111,114,47,99,32,35,102, +32,40,97,110,100,47,99,32,112,97,116,104,45,115,116,114,105,110,103,63,32, +114,101,108,97,116,105,118,101,45,112,97,116,104,63,41,41,23,198,2,28,28, +248,22,133,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23, +198,2,249,22,169,9,194,2,49,11,27,249,22,175,8,247,22,174,8,5,4, +80,65,84,72,27,28,23,194,2,249,80,143,43,44,249,22,165,8,23,198,1, +7,63,9,86,94,23,194,1,9,27,28,249,22,169,9,247,22,180,8,2,43, +249,22,80,248,22,183,15,5,1,46,23,196,1,23,194,1,28,248,22,88,23, 194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,200,2, 28,248,22,186,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248, -22,163,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, -136,16,248,22,81,197,201,28,248,22,186,15,193,250,2,86,203,204,195,251,2, -90,203,204,205,248,22,163,20,198,86,95,28,28,248,22,174,15,23,195,2,10, -28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134,16, -23,195,2,11,12,250,22,181,11,2,7,2,48,23,197,2,28,28,23,195,2, -28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22, -133,16,23,196,2,10,248,22,134,16,23,196,2,11,248,22,133,16,23,196,2, -11,10,12,250,22,181,11,2,7,6,45,45,40,111,114,47,99,32,35,102,32, -40,97,110,100,47,99,32,112,97,116,104,45,115,116,114,105,110,103,63,32,114, -101,108,97,116,105,118,101,45,112,97,116,104,63,41,41,23,198,2,28,28,248, -22,133,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,198, -2,249,22,169,9,194,2,49,11,27,249,22,175,8,247,22,174,8,5,4,80, -65,84,72,27,28,23,194,2,249,80,143,43,44,249,22,165,8,23,198,1,7, -63,9,86,94,23,194,1,9,27,28,249,22,169,9,247,22,180,8,2,43,249, -22,80,248,22,183,15,5,1,46,23,196,1,23,194,1,28,248,22,88,23,194, -2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,200,2,28, -248,22,186,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248,22, -163,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22,136, -16,248,22,81,23,198,2,23,202,2,28,248,22,186,15,23,194,2,250,2,86, -203,204,195,86,94,23,193,1,27,248,22,163,20,23,196,1,28,248,22,88,23, -194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,204,2, -28,248,22,186,15,23,194,2,250,2,86,205,206,195,86,94,23,193,1,27,248, -22,163,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, -136,16,248,22,81,197,205,28,248,22,186,15,193,250,2,86,23,15,23,16,195, -251,2,90,23,15,23,16,23,17,248,22,163,20,198,27,248,22,136,16,23,196, -1,28,248,22,186,15,193,250,2,86,198,199,195,11,250,80,144,42,43,42,196, -197,11,250,80,144,42,43,42,196,11,11,32,95,88,148,8,36,42,58,11,2, -50,222,33,97,0,8,35,114,120,35,34,92,34,34,27,249,22,167,16,23,197, -2,23,198,2,28,23,193,2,86,94,23,196,1,27,248,22,102,23,195,2,27, -27,248,22,111,23,197,1,27,249,22,167,16,23,201,2,23,196,2,28,23,193, -2,86,94,23,194,1,27,248,22,102,23,195,2,27,250,2,95,202,23,204,1, -248,22,111,23,199,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22,179, -16,2,96,23,198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,202, -195,249,22,80,248,22,183,15,195,195,86,95,23,199,1,23,193,1,27,28,249, -22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23,198,1,2,51,194, -28,249,22,150,8,194,2,51,249,22,94,200,9,249,22,80,248,22,183,15,195, -9,27,28,249,22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23,198, -1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,198,195,249,22,80,248, -22,183,15,195,195,86,94,23,193,1,27,28,249,22,169,9,247,22,180,8,2, -43,250,22,179,16,2,96,23,200,1,2,51,196,28,249,22,150,8,194,2,51, -249,22,94,196,9,249,22,80,248,22,183,15,195,9,86,95,28,28,248,22,142, -8,194,10,248,22,153,7,194,12,250,22,181,11,2,8,6,21,21,40,111,114, -47,99,32,98,121,116,101,115,63,32,115,116,114,105,110,103,63,41,196,28,28, -248,22,89,195,249,22,4,22,174,15,196,11,12,250,22,181,11,2,8,6,14, -14,40,108,105,115,116,111,102,32,112,97,116,104,63,41,197,250,2,95,197,195, -28,248,22,153,7,197,248,22,167,8,197,196,28,28,248,22,0,23,195,2,249, -22,48,23,196,2,39,11,20,13,144,80,144,39,46,40,26,29,80,144,8,29, -47,40,249,22,31,11,80,144,8,31,46,40,22,144,15,10,22,145,15,10,22, -146,15,10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22,151, -15,10,22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156,15, -10,22,142,15,11,247,23,194,1,250,22,181,11,2,9,2,52,23,197,1,86, -94,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195,2,28,248, -22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,12,250,22,181,11,23, -196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,12,251,22,183,11,23, -197,1,2,53,2,46,23,198,1,86,94,28,28,248,22,174,15,23,195,2,10, -28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134,16, -23,195,2,11,12,250,22,181,11,23,196,2,2,48,23,197,2,28,248,22,133, -16,23,195,2,12,251,22,183,11,23,197,1,2,53,2,46,23,198,1,86,94, +22,164,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, +136,16,248,22,81,23,198,2,23,202,2,28,248,22,186,15,23,194,2,250,2, +86,203,204,195,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248,22,88, +23,194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,204, +2,28,248,22,186,15,23,194,2,250,2,86,205,206,195,86,94,23,193,1,27, +248,22,164,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248, +22,136,16,248,22,81,197,205,28,248,22,186,15,193,250,2,86,23,15,23,16, +195,251,2,90,23,15,23,16,23,17,248,22,164,20,198,27,248,22,136,16,23, +196,1,28,248,22,186,15,193,250,2,86,198,199,195,11,250,80,144,42,43,42, +196,197,11,250,80,144,42,43,42,196,11,11,32,95,88,148,8,36,42,58,11, +2,50,222,33,97,0,8,35,114,120,35,34,92,34,34,27,249,22,167,16,23, +197,2,23,198,2,28,23,193,2,86,94,23,196,1,27,248,22,102,23,195,2, +27,27,248,22,111,23,197,1,27,249,22,167,16,23,201,2,23,196,2,28,23, +193,2,86,94,23,194,1,27,248,22,102,23,195,2,27,250,2,95,202,23,204, +1,248,22,111,23,199,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22, +179,16,2,96,23,198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94, +202,195,249,22,80,248,22,183,15,195,195,86,95,23,199,1,23,193,1,27,28, +249,22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23,198,1,2,51, +194,28,249,22,150,8,194,2,51,249,22,94,200,9,249,22,80,248,22,183,15, +195,9,27,28,249,22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23, +198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,198,195,249,22,80, +248,22,183,15,195,195,86,94,23,193,1,27,28,249,22,169,9,247,22,180,8, +2,43,250,22,179,16,2,96,23,200,1,2,51,196,28,249,22,150,8,194,2, +51,249,22,94,196,9,249,22,80,248,22,183,15,195,9,86,95,28,28,248,22, +142,8,194,10,248,22,153,7,194,12,250,22,181,11,2,8,6,21,21,40,111, +114,47,99,32,98,121,116,101,115,63,32,115,116,114,105,110,103,63,41,196,28, +28,248,22,89,195,249,22,4,22,174,15,196,11,12,250,22,181,11,2,8,6, +14,14,40,108,105,115,116,111,102,32,112,97,116,104,63,41,197,250,2,95,197, +195,28,248,22,153,7,197,248,22,167,8,197,196,28,28,248,22,0,23,195,2, +249,22,48,23,196,2,39,11,20,13,144,80,144,39,46,40,26,29,80,144,8, +29,47,40,249,22,31,11,80,144,8,31,46,40,22,144,15,10,22,145,15,10, +22,146,15,10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22, +151,15,10,22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156, +15,10,22,142,15,11,247,23,194,1,250,22,181,11,2,9,2,52,23,197,1, 86,94,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195,2,28, 248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,12,250,22,181,11, -23,196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,86,94,23,194,1, -12,251,22,183,11,23,197,2,2,53,2,46,23,198,1,249,22,3,20,20,94, -88,148,8,36,40,50,11,9,223,2,33,101,23,195,1,23,197,1,28,28,248, -22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22,181,11,23,196,1, -2,54,23,197,1,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22,153, +23,196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,12,251,22,183,11, +23,197,1,2,53,2,46,23,198,1,86,94,28,28,248,22,174,15,23,195,2, +10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134, +16,23,195,2,11,12,250,22,181,11,23,196,2,2,48,23,197,2,28,248,22, +133,16,23,195,2,12,251,22,183,11,23,197,1,2,53,2,46,23,198,1,86, +94,86,94,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195,2, +28,248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,12,250,22,181, +11,23,196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,86,94,23,194, +1,12,251,22,183,11,23,197,2,2,53,2,46,23,198,1,249,22,3,20,20, +94,88,148,8,36,40,50,11,9,223,2,33,101,23,195,1,23,197,1,28,28, +248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22,181,11,23,196, +1,2,54,23,197,1,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22, +153,7,23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2, +11,12,250,22,181,11,2,15,2,48,23,196,2,28,248,22,133,16,23,194,2, +12,251,22,183,11,2,15,2,53,2,46,23,197,1,86,95,86,94,86,94,28, +28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,133, +16,23,196,2,10,248,22,134,16,23,196,2,11,12,250,22,181,11,2,15,2, +48,23,198,2,28,248,22,133,16,23,196,2,12,251,22,183,11,2,15,2,53, +2,46,23,199,2,249,22,3,32,0,88,148,8,36,40,49,11,9,222,33,104, +23,198,2,28,28,248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250, +22,181,11,2,15,2,54,23,197,2,252,80,143,44,52,23,199,1,23,200,1, +23,201,1,11,11,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22,153, 7,23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11, -12,250,22,181,11,2,15,2,48,23,196,2,28,248,22,133,16,23,194,2,12, -251,22,183,11,2,15,2,53,2,46,23,197,1,86,95,86,94,86,94,28,28, -248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,133,16, -23,196,2,10,248,22,134,16,23,196,2,11,12,250,22,181,11,2,15,2,48, -23,198,2,28,248,22,133,16,23,196,2,12,251,22,183,11,2,15,2,53,2, -46,23,199,2,249,22,3,32,0,88,148,8,36,40,49,11,9,222,33,104,23, -198,2,28,28,248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22, -181,11,2,15,2,54,23,197,2,252,80,143,44,52,23,199,1,23,200,1,23, -201,1,11,11,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22,153,7, -23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11,12, -250,22,181,11,2,17,2,48,23,196,2,28,248,22,133,16,23,194,2,12,251, -22,183,11,2,17,2,53,2,46,23,197,1,86,96,86,94,28,28,248,22,174, -15,23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,133,16,23,197,2, -10,248,22,134,16,23,197,2,11,12,250,22,181,11,2,17,2,48,23,199,2, -28,248,22,133,16,23,197,2,12,251,22,183,11,2,17,2,53,2,46,23,200, -2,86,94,86,94,28,28,248,22,174,15,23,198,2,10,28,248,22,153,7,23, -198,2,28,248,22,133,16,23,198,2,10,248,22,134,16,23,198,2,11,12,250, -22,181,11,2,17,2,48,23,200,2,28,248,22,133,16,23,198,2,12,251,22, -183,11,2,17,2,53,2,46,23,201,2,249,22,3,32,0,88,148,8,36,40, -49,11,9,222,33,106,23,200,2,28,28,248,22,0,23,195,2,249,22,48,23, -196,2,40,11,12,250,22,181,11,2,17,2,54,23,197,2,252,80,143,44,52, -23,199,1,23,202,1,23,203,1,23,201,1,23,200,1,27,248,22,151,16,2, -55,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16, -23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250, -80,144,49,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95, -23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27, -250,80,144,44,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248, -22,138,16,23,194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42,27, -248,22,151,16,2,58,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1, -28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16, -249,22,136,16,250,80,144,49,43,42,248,22,151,16,2,56,11,11,248,22,151, -16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199, -1,23,196,1,27,250,80,144,44,43,42,248,22,151,16,2,56,23,197,1,10, -28,23,193,2,248,22,138,16,23,194,1,11,249,80,144,41,55,40,40,80,144, -41,8,41,42,27,20,13,144,80,144,40,46,40,26,29,80,144,8,30,47,40, -249,22,31,11,80,144,8,32,46,40,22,144,15,10,22,145,15,10,22,146,15, -10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22,151,15,10, -22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156,15,10,22, -142,15,11,247,22,148,6,28,248,22,149,2,193,192,11,27,28,23,195,2,249, -22,128,16,23,197,1,6,11,11,99,111,110,102,105,103,46,114,107,116,100,86, -94,23,195,1,11,27,28,23,194,2,28,248,22,186,15,23,195,2,249,22,140, -6,23,196,1,80,144,43,8,42,42,11,11,28,192,192,21,17,1,0,250,22, -158,2,23,196,1,2,59,247,22,171,8,250,22,158,2,195,2,59,247,22,171, -8,28,248,22,153,7,23,195,2,27,248,22,182,15,23,196,1,28,248,22,135, -16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,43,54,42,28,23, -193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,142,8,23,195,2,27, -248,22,183,15,23,196,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23, -195,1,27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247,22, -152,16,28,248,22,174,15,23,195,2,28,248,22,135,16,23,195,2,193,249,22, -136,16,23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23,193, -1,247,22,152,16,193,27,248,22,151,16,2,55,28,248,22,135,16,23,194,2, -248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89,146, -42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22,151,16, -2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22,138, -16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22,151, -16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28,248, -22,135,16,23,195,2,193,249,22,136,16,23,196,1,27,249,80,144,44,55,40, -39,80,144,44,8,43,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16, -28,248,22,135,16,23,195,2,248,22,138,16,23,195,1,28,248,22,134,16,23, -195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80, -144,48,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23, -195,1,23,194,1,248,22,138,16,249,22,136,16,23,200,1,23,196,1,27,250, -80,144,43,43,42,248,22,151,16,2,56,23,198,1,10,28,23,193,2,248,22, -138,16,23,194,1,11,28,248,22,88,23,196,2,9,28,248,22,81,23,196,2, -249,22,80,27,248,22,162,20,23,199,2,28,248,22,153,7,23,194,2,27,248, -22,182,15,23,195,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195, -1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152, -16,28,248,22,142,8,23,194,2,27,248,22,183,15,23,195,1,28,248,22,135, -16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,46,54,42,28,23, -193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,174,15,23,194,2,28, -248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,45,54, -42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,192,27,248,22,163,20, -23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80, -248,80,144,45,60,42,248,22,162,20,23,197,2,27,248,22,163,20,23,197,1, -28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144, -48,60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, -22,163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, -1,248,22,163,20,23,198,1,249,22,94,23,199,2,27,248,22,163,20,23,197, +12,250,22,181,11,2,17,2,48,23,196,2,28,248,22,133,16,23,194,2,12, +251,22,183,11,2,17,2,53,2,46,23,197,1,86,96,86,94,28,28,248,22, +174,15,23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,133,16,23,197, +2,10,248,22,134,16,23,197,2,11,12,250,22,181,11,2,17,2,48,23,199, +2,28,248,22,133,16,23,197,2,12,251,22,183,11,2,17,2,53,2,46,23, +200,2,86,94,86,94,28,28,248,22,174,15,23,198,2,10,28,248,22,153,7, +23,198,2,28,248,22,133,16,23,198,2,10,248,22,134,16,23,198,2,11,12, +250,22,181,11,2,17,2,48,23,200,2,28,248,22,133,16,23,198,2,12,251, +22,183,11,2,17,2,53,2,46,23,201,2,249,22,3,32,0,88,148,8,36, +40,49,11,9,222,33,106,23,200,2,28,28,248,22,0,23,195,2,249,22,48, +23,196,2,40,11,12,250,22,181,11,2,17,2,54,23,197,2,252,80,143,44, +52,23,199,1,23,202,1,23,203,1,23,201,1,23,200,1,27,248,22,151,16, +2,55,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134, +16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16, +250,80,144,49,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86, +95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1, +27,250,80,144,44,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2, +248,22,138,16,23,194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42, +27,248,22,151,16,2,58,28,248,22,135,16,23,194,2,248,22,138,16,23,194, +1,28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131, +16,249,22,136,16,250,80,144,49,43,42,248,22,151,16,2,56,11,11,248,22, +151,16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23, +199,1,23,196,1,27,250,80,144,44,43,42,248,22,151,16,2,56,23,197,1, +10,28,23,193,2,248,22,138,16,23,194,1,11,249,80,144,41,55,40,40,80, +144,41,8,41,42,27,20,13,144,80,144,40,46,40,26,29,80,144,8,30,47, +40,249,22,31,11,80,144,8,32,46,40,22,144,15,10,22,145,15,10,22,146, +15,10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22,151,15, +10,22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156,15,10, +22,142,15,11,247,22,148,6,28,248,22,149,2,193,192,11,27,28,23,195,2, +249,22,128,16,23,197,1,6,11,11,99,111,110,102,105,103,46,114,107,116,100, +86,94,23,195,1,11,27,28,23,194,2,28,248,22,186,15,23,195,2,249,22, +140,6,23,196,1,80,144,43,8,42,42,11,11,28,192,192,21,17,1,0,250, +22,158,2,23,196,1,2,59,247,22,171,8,250,22,158,2,195,2,59,247,22, +171,8,28,248,22,153,7,23,195,2,27,248,22,182,15,23,196,1,28,248,22, +135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,43,54,42,28, +23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,142,8,23,195,2, +27,248,22,183,15,23,196,1,28,248,22,135,16,23,194,2,192,249,22,136,16, +23,195,1,27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247, +22,152,16,28,248,22,174,15,23,195,2,28,248,22,135,16,23,195,2,193,249, +22,136,16,23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23, +193,1,247,22,152,16,193,27,248,22,151,16,2,55,28,248,22,135,16,23,194, +2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89, +146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22,151, +16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22, +138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, +151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28, +248,22,135,16,23,195,2,193,249,22,136,16,23,196,1,27,249,80,144,44,55, +40,39,80,144,44,8,43,42,28,23,193,2,192,86,94,23,193,1,247,22,152, +16,28,248,22,135,16,23,195,2,248,22,138,16,23,195,1,28,248,22,134,16, +23,195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250, +80,144,48,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95, +23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,200,1,23,196,1,27, +250,80,144,43,43,42,248,22,151,16,2,56,23,198,1,10,28,23,193,2,248, +22,138,16,23,194,1,11,28,248,22,88,23,196,2,9,28,248,22,81,23,196, +2,249,22,80,27,248,22,163,20,23,199,2,28,248,22,153,7,23,194,2,27, +248,22,182,15,23,195,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23, +195,1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22, +152,16,28,248,22,142,8,23,194,2,27,248,22,183,15,23,195,1,28,248,22, +135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,46,54,42,28, +23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,174,15,23,194,2, +28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,45, +54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,192,27,248,22,164, +20,23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22, +80,248,80,144,45,60,42,248,22,163,20,23,197,2,27,248,22,164,20,23,197, 1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80, -144,48,60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1, -248,22,163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, -204,1,248,22,163,20,23,198,1,249,22,94,23,196,2,27,248,22,163,20,23, -199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248, -80,144,45,60,42,248,22,162,20,23,197,2,27,248,22,163,20,23,197,1,28, -248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144,48, -60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248,22, -163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204,1, -248,22,163,20,23,198,1,249,22,94,23,199,2,27,248,22,163,20,23,197,1, +144,48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204,1, +248,22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, +204,1,248,22,164,20,23,198,1,249,22,94,23,199,2,27,248,22,164,20,23, +197,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248, +80,144,48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204, +1,248,22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42, +23,204,1,248,22,164,20,23,198,1,249,22,94,23,196,2,27,248,22,164,20, +23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80, +248,80,144,45,60,42,248,22,163,20,23,197,2,27,248,22,164,20,23,197,1, 28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144, -48,60,42,248,22,162,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, -22,163,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, -1,248,22,163,20,23,198,1,27,250,22,158,2,23,198,1,23,199,1,11,28, -192,249,80,144,42,8,44,42,198,194,196,27,248,22,151,16,2,58,28,248,22, -135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90, -144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43, -42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23, -194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44, -43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23, -194,1,11,27,248,80,144,41,58,42,249,80,144,43,55,40,40,80,144,43,8, -45,42,27,27,250,22,158,2,23,198,2,72,108,105,110,107,115,45,102,105,108, -101,11,27,28,23,194,2,23,194,1,86,94,23,194,1,249,22,128,16,27,250, -22,158,2,23,202,2,71,115,104,97,114,101,45,100,105,114,11,28,192,192,249, -22,128,16,64,117,112,6,5,5,115,104,97,114,101,2,60,28,248,22,153,7, -23,194,2,27,248,22,182,15,23,195,1,28,248,22,135,16,23,194,2,192,249, -22,136,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94,23, -193,1,247,22,152,16,28,248,22,142,8,23,194,2,27,248,22,183,15,23,195, -1,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144, -47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,174, -15,23,194,2,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27, -247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,192, -250,22,94,248,22,90,11,28,247,22,159,16,28,247,22,160,16,248,22,90,250, -22,128,16,248,22,151,16,2,61,250,22,158,2,23,204,2,2,59,247,22,171, -8,2,60,9,9,28,247,22,160,16,250,80,144,47,8,23,42,23,200,1,1, -18,108,105,110,107,115,45,115,101,97,114,99,104,45,102,105,108,101,115,248,22, -90,23,200,1,9,248,22,173,13,23,194,1,249,22,14,80,144,41,8,26,41, -28,248,22,129,13,23,197,2,86,94,23,196,1,32,0,88,148,8,36,39,44, -11,9,222,11,20,20,94,88,148,8,36,39,46,11,9,223,3,33,124,23,196, -1,32,126,88,148,39,40,59,11,2,50,222,33,127,90,144,42,11,89,146,42, -39,11,248,22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174, -15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0, -88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22, -131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2, -28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, -39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197, -1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187, -15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9, -222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95,23, -195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194,2, -249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248,2, -126,23,194,1,11,11,11,11,32,128,2,88,148,8,36,40,58,11,2,50,222, -33,129,2,27,249,22,163,6,8,128,128,23,196,2,28,248,22,148,7,23,194, -2,9,249,22,80,23,195,1,27,249,22,163,6,8,128,128,23,199,2,28,248, -22,148,7,23,194,2,9,249,22,80,23,195,1,27,249,22,163,6,8,128,128, -23,202,2,28,248,22,148,7,23,194,2,9,249,22,80,23,195,1,27,249,22, -163,6,8,128,128,23,205,2,28,248,22,148,7,23,194,2,9,249,22,80,23, -195,1,248,2,128,2,23,206,1,27,249,22,163,6,8,128,128,23,196,2,28, -248,22,142,8,23,194,2,28,249,22,132,4,248,22,147,8,23,196,2,8,128, -128,249,22,1,22,154,8,249,22,80,23,197,1,27,249,22,163,6,8,128,128, -23,201,2,28,248,22,148,7,23,194,2,9,249,22,80,23,195,1,27,249,22, -163,6,8,128,128,23,204,2,28,248,22,148,7,23,194,2,9,249,22,80,23, -195,1,27,249,22,163,6,8,128,128,23,207,2,28,248,22,148,7,23,194,2, -9,249,22,80,23,195,1,27,249,22,163,6,8,128,128,23,210,2,28,248,22, -148,7,23,194,2,9,249,22,80,23,195,1,248,2,128,2,23,211,1,192,192, -248,22,133,6,23,194,1,20,13,144,80,144,40,8,28,40,80,144,40,8,46, -42,27,28,249,22,189,8,248,22,180,8,2,62,41,90,144,42,11,89,146,42, -39,11,248,22,131,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22,174, -15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0, -88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22, -131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2, -28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36, -39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197, -1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187, -15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9, -222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95,23, -195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194,2, -249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248,2, -126,23,194,1,11,11,11,11,11,28,248,22,186,15,23,195,2,27,28,249,22, -189,8,248,22,180,8,2,62,41,249,22,145,6,23,197,2,32,0,88,148,8, -36,39,44,11,9,222,11,11,86,94,28,23,194,2,248,22,147,6,23,195,1, -86,94,23,194,1,12,249,22,80,27,248,22,188,5,23,199,1,250,22,44,22, -35,88,148,39,39,8,24,11,9,223,3,33,130,2,20,20,94,88,148,8,36, -39,46,11,9,223,3,33,131,2,23,196,1,194,249,22,80,11,194,28,28,23, -195,2,28,248,22,82,23,196,2,248,22,167,9,249,22,175,14,39,248,22,163, -20,23,199,2,11,11,194,86,94,23,195,1,249,22,12,20,20,94,88,148,8, -32,39,61,16,4,39,8,128,80,8,240,0,64,0,0,39,9,224,2,3,33, -132,2,23,196,1,80,144,41,8,26,41,27,248,22,167,9,194,28,192,192,248, -22,167,9,248,22,81,195,86,95,28,248,22,150,12,23,198,2,27,247,22,142, -12,28,249,22,132,12,23,195,2,2,63,251,22,138,12,23,197,1,2,63,250, -22,137,8,6,42,42,101,114,114,111,114,32,114,101,97,100,105,110,103,32,99, -111,108,108,101,99,116,105,111,110,32,108,105,110,107,115,32,102,105,108,101,32, -126,115,58,32,126,97,23,203,2,248,22,146,12,23,206,2,247,22,27,12,12, -28,23,193,2,250,22,156,2,80,144,45,8,25,41,23,198,1,249,22,80,23, -198,1,21,17,0,0,86,95,23,195,1,23,193,1,12,28,248,22,150,12,23, -198,2,86,94,23,197,1,248,23,195,1,247,22,138,2,196,88,148,39,40,58, -8,240,0,0,0,2,9,226,0,2,1,3,33,135,2,20,20,94,248,22,148, -6,23,194,2,28,248,22,148,7,248,22,148,6,23,195,1,12,248,22,177,11, -6,30,30,101,120,112,101,99,116,101,100,32,97,32,115,105,110,103,108,101,32, -83,45,101,120,112,114,101,115,115,105,111,110,248,22,133,6,23,194,1,28,248, -22,89,193,28,28,249,22,128,4,41,248,22,93,195,10,249,22,128,4,42,248, -22,93,195,28,28,248,22,153,7,248,22,81,194,10,28,249,22,169,9,2,64, -248,22,162,20,195,10,249,22,169,9,2,65,248,22,162,20,195,28,27,248,22, -102,194,28,248,22,174,15,193,10,28,248,22,153,7,193,28,248,22,133,16,193, -10,248,22,134,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22,180, -16,248,22,111,195,11,11,11,11,28,248,22,187,15,249,22,128,16,23,196,2, -23,198,2,27,248,22,68,248,22,178,15,23,198,1,250,22,156,2,23,198,2, -23,196,2,249,22,80,23,199,1,250,22,158,2,23,203,1,23,201,1,9,12, -250,22,156,2,23,197,1,23,198,1,249,22,80,23,198,1,23,201,1,28,28, -248,22,88,248,22,104,23,197,2,10,249,22,171,16,248,22,111,23,198,2,247, -22,171,8,27,248,22,138,16,249,22,136,16,248,22,102,23,200,2,23,198,1, -28,249,22,169,9,248,22,162,20,23,199,2,2,65,86,94,23,196,1,249,22, -3,20,20,94,88,148,8,36,40,56,11,9,224,3,2,33,140,2,23,196,1, -248,22,141,16,23,196,1,28,249,22,169,9,248,22,162,20,23,199,2,2,64, -86,94,23,196,1,86,94,28,250,22,158,2,23,197,2,11,11,12,250,22,156, -2,23,197,2,11,9,249,22,164,2,23,196,2,20,20,95,88,148,8,36,41, -53,11,9,224,3,2,33,141,2,23,195,1,23,196,1,27,248,22,68,248,22, -162,20,23,199,1,250,22,156,2,23,198,2,23,196,2,249,22,80,248,22,129, -2,23,200,1,250,22,158,2,23,203,1,23,201,1,9,12,250,22,156,2,23, -196,1,23,197,1,248,22,95,23,199,1,27,28,28,23,194,2,248,22,167,9, -248,22,81,23,196,2,10,9,27,249,22,188,5,23,198,2,68,98,105,110,97, -114,121,250,22,44,22,35,88,148,8,36,39,47,11,9,223,3,33,137,2,20, -20,94,88,148,8,36,39,46,11,9,223,3,33,138,2,23,196,1,86,94,28, -28,248,22,89,23,194,2,249,22,4,32,0,88,148,8,36,40,48,11,9,222, -33,139,2,23,195,2,11,12,248,22,177,11,6,18,18,105,108,108,45,102,111, -114,109,101,100,32,99,111,110,116,101,110,116,27,247,22,138,2,27,90,144,42, -11,89,146,42,39,11,248,22,131,16,23,201,2,192,86,96,249,22,3,20,20, -94,88,148,8,36,40,57,11,9,224,2,3,33,142,2,23,195,1,23,197,1, -249,22,164,2,195,88,148,8,36,41,51,11,9,223,3,33,143,2,250,22,156, -2,80,144,47,8,25,41,23,200,1,249,22,80,23,201,1,198,193,20,13,144, -80,144,40,8,28,40,250,80,144,43,8,47,42,23,198,2,23,196,2,11,27, -250,22,158,2,80,144,44,8,25,41,23,197,2,21,143,11,17,0,0,27,248, -22,81,23,195,2,27,249,80,144,45,8,27,42,23,198,2,23,196,2,28,249, -22,171,9,23,195,2,23,196,1,248,22,163,20,195,86,94,23,195,1,20,13, -144,80,144,43,8,28,40,250,80,144,46,8,47,42,23,201,1,23,199,2,23, -196,2,27,20,20,95,88,148,8,36,39,55,8,240,0,0,0,2,9,225,5, -4,1,33,144,2,23,194,1,23,197,1,28,249,22,48,23,195,2,39,20,13, -144,80,144,44,46,40,26,29,80,144,8,34,47,40,249,22,31,11,80,144,8, -36,46,40,22,144,15,10,22,145,15,10,22,146,15,10,22,149,15,10,22,148, -15,11,22,150,15,10,22,147,15,10,22,151,15,10,22,152,15,10,22,153,15, -10,22,154,15,10,22,155,15,11,22,156,15,10,22,142,15,11,247,23,193,1, -250,22,181,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39,40, -8,43,16,4,8,128,6,8,128,104,8,240,0,128,0,0,39,9,224,1,2, -33,145,2,23,195,1,0,7,35,114,120,34,47,43,34,28,248,22,153,7,23, -195,2,27,249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128, -4,248,22,101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7, -250,22,175,7,23,200,1,39,248,22,101,23,199,1,23,198,1,249,22,7,250, -22,175,7,23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23, -201,1,248,22,103,23,200,1,23,200,1,249,22,7,23,197,1,23,198,1,90, -144,42,11,89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1,28, -249,22,169,9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23, -200,1,27,249,22,80,23,197,1,23,201,1,28,248,22,153,7,23,195,2,27, -249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128,4,248,22, -101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7,250,22,175, -7,23,200,1,39,248,22,101,23,199,1,23,196,1,249,22,7,250,22,175,7, -23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23,201,1,248, -22,103,23,200,1,23,198,1,249,22,7,23,197,1,23,196,1,90,144,42,11, -89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1,28,249,22,169, -9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23,198,1,249, -80,144,48,8,31,42,194,249,22,80,197,199,28,248,22,88,23,196,2,9,28, -248,22,81,23,196,2,28,248,22,149,2,248,22,162,20,23,197,2,250,22,94, -249,22,2,22,129,2,250,22,158,2,248,22,162,20,23,204,2,23,202,2,9, -250,22,158,2,248,22,162,20,23,202,2,11,9,27,248,22,163,20,23,200,1, -28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248, -22,162,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22, -162,20,23,202,2,23,206,2,9,250,22,158,2,248,22,162,20,23,200,2,11, -9,249,80,144,48,8,48,42,23,203,1,248,22,163,20,23,199,1,27,248,80, -144,45,8,30,42,248,22,162,20,23,196,2,250,22,94,250,22,158,2,23,199, -2,23,205,2,9,250,22,158,2,23,199,1,11,9,249,80,144,49,8,48,42, -23,204,1,248,22,163,20,23,200,1,249,22,94,247,22,155,16,249,80,144,47, -8,48,42,23,202,1,248,22,163,20,23,198,1,27,248,80,144,41,8,30,42, -248,22,162,20,23,198,2,250,22,94,250,22,158,2,23,199,2,23,201,2,9, -250,22,158,2,23,199,1,11,9,27,248,22,163,20,23,201,1,28,248,22,88, -23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,162,20,23, -195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,162,20,23,202, -2,23,207,2,9,250,22,158,2,248,22,162,20,23,200,2,11,9,249,80,144, -49,8,48,42,23,204,1,248,22,163,20,23,199,1,27,248,80,144,46,8,30, -42,248,22,162,20,23,196,2,250,22,94,250,22,158,2,23,199,2,23,206,2, -9,250,22,158,2,23,199,1,11,9,249,80,144,50,8,48,42,23,205,1,248, -22,163,20,23,200,1,249,22,94,247,22,155,16,249,80,144,48,8,48,42,23, -203,1,248,22,163,20,23,198,1,249,22,94,247,22,155,16,27,248,22,163,20, -23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22, -149,2,248,22,162,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158, -2,248,22,162,20,23,202,2,23,205,2,9,250,22,158,2,248,22,162,20,23, -200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,163,20,23,199,1, -27,248,80,144,44,8,30,42,248,22,162,20,23,196,2,250,22,94,250,22,158, -2,23,199,2,23,204,2,9,250,22,158,2,23,199,1,11,9,249,80,144,48, -8,48,42,23,203,1,248,22,163,20,23,200,1,249,22,94,247,22,155,16,249, -80,144,46,8,48,42,23,201,1,248,22,163,20,23,198,1,32,150,2,88,148, -8,36,40,50,11,2,50,222,33,151,2,28,248,22,88,248,22,82,23,195,2, -248,22,90,27,248,22,162,20,195,28,248,22,174,15,193,248,22,178,15,193,192, -250,22,91,27,248,22,162,20,23,198,2,28,248,22,174,15,193,248,22,178,15, -193,192,2,67,248,2,150,2,248,22,163,20,23,198,1,250,22,137,8,6,7, -7,10,32,126,97,32,126,97,6,1,1,32,23,196,1,249,22,137,8,6,6, -6,10,32,32,32,126,97,248,22,132,2,23,196,1,32,154,2,88,148,39,41, -51,11,68,102,105,108,116,101,114,222,33,155,2,28,248,22,88,23,195,2,9, -28,248,23,194,2,248,22,81,23,196,2,249,22,80,248,22,162,20,23,197,2, -249,2,154,2,23,197,1,248,22,163,20,23,199,1,249,2,154,2,23,195,1, -248,22,163,20,23,197,1,28,248,22,88,23,201,2,86,95,23,200,1,23,199, -1,28,23,201,2,28,197,249,22,128,16,202,199,200,27,28,248,22,88,23,198, -2,2,66,249,22,1,22,176,7,248,2,150,2,23,200,2,248,23,199,1,251, -22,137,8,6,70,70,99,111,108,108,101,99,116,105,111,110,32,110,111,116,32, -102,111,117,110,100,10,32,32,99,111,108,108,101,99,116,105,111,110,58,32,126, -115,10,32,32,105,110,32,99,111,108,108,101,99,116,105,111,110,32,100,105,114, -101,99,116,111,114,105,101,115,58,126,97,126,97,28,248,22,88,23,203,1,28, -248,22,174,15,23,202,2,248,22,178,15,23,202,1,23,201,1,250,22,176,7, -28,248,22,174,15,23,205,2,248,22,178,15,23,205,1,23,204,1,2,67,23, -201,2,249,22,1,22,176,7,249,22,2,32,0,88,148,8,36,40,48,11,9, -222,33,152,2,27,248,22,93,23,206,2,27,248,22,93,247,22,155,16,28,249, -22,129,4,249,22,184,3,23,198,2,23,197,2,44,23,206,2,249,22,94,247, -22,155,16,248,22,90,249,22,137,8,6,50,50,46,46,46,32,91,126,97,32, -97,100,100,105,116,105,111,110,97,108,32,108,105,110,107,101,100,32,97,110,100, -32,112,97,99,107,97,103,101,32,100,105,114,101,99,116,111,114,105,101,115,93, -249,22,184,3,23,201,1,23,200,1,28,249,22,5,22,131,2,23,202,2,250, -22,137,8,6,49,49,10,32,32,32,115,117,98,45,99,111,108,108,101,99,116, -105,111,110,58,32,126,115,10,32,32,105,110,32,112,97,114,101,110,116,32,100, -105,114,101,99,116,111,114,105,101,115,58,126,97,23,201,1,249,22,1,22,176, -7,249,22,2,32,0,88,148,8,36,40,48,11,9,222,33,153,2,249,2,154, -2,22,131,2,23,209,1,86,95,23,200,1,23,198,1,2,66,27,248,22,81, -23,202,2,27,28,248,22,174,15,23,195,2,249,22,128,16,23,196,1,23,199, -2,248,22,132,2,23,195,1,28,28,248,22,174,15,248,22,162,20,23,204,2, -248,22,187,15,23,194,2,10,27,250,22,1,22,128,16,23,197,1,23,202,2, -28,28,248,22,88,23,200,2,10,248,22,187,15,23,194,2,28,23,201,2,28, -28,250,80,144,45,8,32,42,195,203,204,10,27,28,248,22,174,15,202,248,22, -178,15,202,201,19,248,22,156,7,23,195,2,27,28,249,22,132,4,23,196,4, -43,28,249,22,159,7,6,4,4,46,114,107,116,249,22,175,7,23,199,2,249, -22,184,3,23,200,4,43,249,22,176,7,250,22,175,7,23,200,1,39,249,22, -184,3,23,201,4,43,6,3,3,46,115,115,86,94,23,195,1,11,11,28,23, -193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249,22, -128,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16,23, -17,248,22,163,20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8,49, -42,204,205,206,23,15,23,16,23,17,248,22,163,20,23,19,23,19,26,8,80, -144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,163,20,23,18,23,18, -90,144,41,11,89,146,41,39,11,249,80,144,43,8,31,42,23,199,1,23,200, -1,27,248,22,68,28,248,22,174,15,195,248,22,178,15,195,194,27,27,247,22, -156,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149, -2,248,22,162,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2, -248,22,162,20,23,202,2,23,203,2,9,250,22,158,2,248,22,162,20,23,200, -2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,163,20,23,199,1,27, -248,80,144,46,8,30,42,248,22,162,20,23,196,2,250,22,94,250,22,158,2, -23,199,2,23,202,2,9,250,22,158,2,23,199,1,11,9,249,80,144,50,8, -48,42,23,201,1,248,22,163,20,23,200,1,249,22,94,247,22,155,16,249,80, -144,48,8,48,42,23,199,1,248,22,163,20,23,198,1,26,8,80,144,51,8, -49,42,200,202,203,205,23,16,23,17,200,11,32,158,2,88,148,8,36,42,59, -11,2,50,222,33,159,2,28,248,22,133,4,23,196,2,86,94,23,195,1,19, -248,22,147,8,23,195,2,19,248,22,147,8,23,196,2,249,22,184,15,27,251, -22,154,8,250,22,153,8,23,205,2,39,23,204,4,2,51,249,22,153,8,23, -204,1,23,202,4,2,68,28,248,22,133,4,248,22,147,8,23,195,2,86,94, -23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248,22,175,15,198, -248,22,176,15,198,247,22,177,15,2,2,27,248,22,182,3,23,197,1,28,249, -22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248,22,181,3,23, -195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204, -1,2,71,249,22,153,8,23,204,1,23,202,1,2,68,28,248,22,133,4,248, -22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, -202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,250,2,158,2, -196,197,195,248,22,186,15,27,250,22,128,16,23,200,1,23,202,1,23,199,1, -28,249,22,169,9,23,197,2,66,115,97,109,101,192,28,248,22,133,16,23,196, -2,249,22,128,16,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249,22, -5,20,20,96,88,148,39,40,54,47,9,226,5,4,2,6,33,160,2,23,199, -1,23,195,1,23,197,1,23,196,1,27,248,22,186,15,249,22,128,16,23,198, -2,23,199,2,28,23,193,2,192,86,94,23,193,1,28,23,197,1,27,90,144, -41,11,89,146,41,39,11,250,80,144,46,8,34,42,23,202,2,2,68,2,37, -27,248,22,180,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248,22, -147,8,23,198,1,28,248,22,175,15,195,249,22,128,16,196,194,192,27,247,22, -157,16,249,22,5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3,33, -161,2,23,196,1,23,195,1,23,199,1,247,22,158,16,11,86,95,28,28,248, -22,175,15,23,194,2,10,28,248,22,174,15,23,194,2,10,28,248,22,153,7, -23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11,12, -252,22,181,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22,153, -7,23,195,2,10,248,22,142,8,23,195,2,86,94,23,194,1,12,252,22,181, -11,23,200,2,2,72,40,23,198,2,23,199,1,90,144,42,11,89,146,42,39, -11,248,22,131,16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86,95, -23,198,1,23,196,1,12,250,22,184,11,23,201,1,2,73,23,199,1,249,22, -7,23,195,1,23,196,1,32,164,2,88,148,8,36,46,61,11,2,74,222,33, -165,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2,39,23,207, -1,23,205,1,249,23,203,1,23,202,1,23,208,1,28,248,22,153,7,23,204, -2,249,22,168,8,23,205,1,8,63,23,203,1,28,248,22,133,4,248,22,147, -8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,201,192, -28,248,22,175,15,197,248,22,176,15,197,247,22,177,15,32,166,2,88,148,8, -36,45,8,24,11,2,50,222,33,167,2,28,248,22,133,4,23,199,2,86,95, -23,198,1,23,194,1,19,248,22,147,8,23,195,2,19,248,22,147,8,23,196, -2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204,4, -2,51,249,23,206,1,23,204,1,23,202,4,28,248,22,153,7,23,207,2,249, -22,168,8,23,208,1,8,63,23,206,1,28,248,22,133,4,248,22,147,8,23, -195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,204,192,28,248, -22,175,15,200,248,22,176,15,200,247,22,177,15,2,2,27,248,22,182,3,23, -200,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248, -22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205, -2,39,23,204,1,23,203,1,249,23,206,1,23,204,1,23,202,1,28,248,22, -153,7,23,207,2,249,22,168,8,23,208,1,8,63,23,206,1,28,248,22,133, -4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69, -2,70,204,192,28,248,22,175,15,200,248,22,176,15,200,247,22,177,15,28,248, -22,133,4,23,194,2,86,95,23,195,1,23,193,1,19,248,22,147,8,23,196, -2,19,248,22,147,8,23,197,2,249,22,184,15,27,251,22,154,8,250,22,153, -8,23,206,2,39,23,204,4,2,51,249,23,207,1,23,205,1,23,202,4,28, -248,22,153,7,23,208,2,249,22,168,8,23,209,1,8,63,23,207,1,28,248, -22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37, -2,69,2,70,205,192,28,248,22,175,15,201,248,22,176,15,201,247,22,177,15, -2,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148,8, -23,199,2,23,197,2,27,248,22,181,3,23,195,2,249,22,184,15,27,251,22, -154,8,250,22,153,8,23,206,2,39,23,204,1,23,204,1,249,23,207,1,23, -205,1,23,202,1,28,248,22,153,7,23,208,2,249,22,168,8,23,209,1,8, -63,23,207,1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1, -251,22,183,11,2,37,2,69,2,70,205,192,28,248,22,175,15,201,248,22,176, -15,201,247,22,177,15,28,248,22,133,4,193,254,2,164,2,201,203,204,205,248, -22,147,8,202,2,51,248,22,147,8,202,27,248,22,182,3,194,28,249,22,169, -9,8,46,249,22,148,8,199,196,254,2,164,2,202,204,205,206,199,203,248,22, -181,3,200,253,2,166,2,201,202,203,204,205,198,90,144,41,11,89,146,41,39, -11,86,95,28,28,248,22,175,15,23,199,2,10,28,248,22,174,15,23,199,2, -10,28,248,22,153,7,23,199,2,28,248,22,133,16,23,199,2,10,248,22,134, -16,23,199,2,11,12,252,22,181,11,23,200,2,2,42,39,23,203,2,23,204, -2,28,28,248,22,153,7,23,200,2,10,248,22,142,8,23,200,2,12,252,22, -181,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146,42, -39,11,248,22,131,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250,22, -184,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,180,15,23, -196,1,27,19,248,22,147,8,23,196,2,28,248,22,133,4,23,194,4,86,94, -23,199,1,19,248,22,147,8,23,197,2,19,248,22,147,8,23,198,2,249,22, -184,15,27,251,22,154,8,250,22,153,8,23,207,2,39,23,204,4,2,51,249, -23,211,1,23,206,1,23,202,4,28,248,22,153,7,23,212,2,249,22,168,8, -23,213,1,8,63,23,211,1,28,248,22,133,4,248,22,147,8,23,195,2,86, -94,23,193,1,251,22,183,11,2,37,2,69,2,70,23,17,192,28,248,22,175, -15,205,248,22,176,15,205,247,22,177,15,2,2,27,248,22,182,3,23,195,4, -28,249,22,169,9,8,46,249,22,148,8,23,200,2,23,197,2,27,248,22,181, -3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,207,2,39, -23,204,1,23,208,1,249,23,211,1,23,206,1,23,202,1,28,248,22,153,7, -23,212,2,249,22,168,8,23,213,1,8,63,23,211,1,28,248,22,133,4,248, -22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, -23,17,192,28,248,22,175,15,205,248,22,176,15,205,247,22,177,15,28,248,22, -133,4,23,194,2,86,95,23,200,1,23,193,1,254,2,164,2,23,203,2,23, -208,1,23,209,1,23,210,1,248,22,147,8,23,204,2,2,51,248,22,147,8, -23,204,1,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148, -8,23,201,2,23,197,2,254,2,164,2,23,204,1,23,209,1,23,210,1,23, -211,1,23,200,2,23,208,1,248,22,181,3,23,201,1,253,2,166,2,23,203, -1,23,207,1,23,208,1,23,209,1,23,210,1,23,199,1,2,28,248,22,175, -15,195,249,22,128,16,196,194,192,32,169,2,88,148,8,36,43,61,11,2,50, -222,33,170,2,28,248,22,133,4,23,197,2,86,94,23,196,1,19,248,22,147, -8,23,195,2,35,248,22,147,8,23,196,2,249,22,184,15,27,251,22,154,8, -250,22,153,8,23,205,1,39,23,204,4,2,51,2,51,28,248,22,153,7,23, -205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22, -147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202, -192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,27,248,22,182, -3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2, -35,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8, -23,205,1,39,23,204,1,2,51,2,51,28,248,22,153,7,23,205,2,249,22, -168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22,147,8,23,195, -2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248,22, -175,15,198,248,22,176,15,198,247,22,177,15,28,248,22,133,4,23,194,2,86, -94,23,193,1,19,248,22,147,8,23,196,2,35,248,22,147,8,23,197,2,249, -22,184,15,27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,4,2,51, -2,51,28,248,22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205, -1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183, -11,2,37,2,69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199,247, -22,177,15,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22, -148,8,23,199,2,23,197,2,35,248,22,181,3,23,195,2,249,22,184,15,27, -251,22,154,8,250,22,153,8,23,206,1,39,23,204,1,2,51,2,51,28,248, -22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205,1,28,248,22, +48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, +22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, +1,248,22,164,20,23,198,1,249,22,94,23,199,2,27,248,22,164,20,23,197, +1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80, +144,48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204,1, +248,22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, +204,1,248,22,164,20,23,198,1,27,250,22,158,2,23,198,1,23,199,1,11, +28,192,249,80,144,42,8,44,42,198,194,196,27,248,22,151,16,2,58,28,248, +22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2, +90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49, +43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1, +23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144, +44,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16, +23,194,1,11,27,248,80,144,41,58,42,249,80,144,43,55,40,40,80,144,43, +8,45,42,27,27,250,22,158,2,23,198,2,72,108,105,110,107,115,45,102,105, +108,101,11,27,28,23,194,2,23,194,1,86,94,23,194,1,249,22,128,16,27, +250,22,158,2,23,202,2,71,115,104,97,114,101,45,100,105,114,11,28,192,192, +249,22,128,16,64,117,112,6,5,5,115,104,97,114,101,2,60,28,248,22,153, +7,23,194,2,27,248,22,182,15,23,195,1,28,248,22,135,16,23,194,2,192, +249,22,136,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94, +23,193,1,247,22,152,16,28,248,22,142,8,23,194,2,27,248,22,183,15,23, +195,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80, +144,47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22, +174,15,23,194,2,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1, +27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16, +192,250,22,94,248,22,90,11,28,247,22,159,16,28,247,22,160,16,248,22,90, +250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,204,2,2,59,247,22, +171,8,2,60,9,9,28,247,22,160,16,250,80,144,47,8,23,42,23,200,1, +1,18,108,105,110,107,115,45,115,101,97,114,99,104,45,102,105,108,101,115,248, +22,90,23,200,1,9,248,22,173,13,23,194,1,249,22,14,80,144,41,8,26, +41,28,248,22,129,13,23,197,2,86,94,23,196,1,32,0,88,148,8,36,39, +44,11,9,222,11,20,20,94,88,148,8,36,39,46,11,9,223,3,33,124,23, +196,1,32,126,88,148,39,40,59,11,2,50,222,33,127,90,144,42,11,89,146, +42,39,11,248,22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22, +174,15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32, +0,88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248, +22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194, +2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8, +36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23, +197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22, +187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11, +9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95, +23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194, +2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248, +2,126,23,194,1,11,11,11,11,32,128,2,88,148,8,36,40,58,11,2,50, +222,33,129,2,27,249,22,163,6,8,128,128,23,196,2,28,248,22,148,7,23, +194,2,9,249,22,80,23,195,1,27,249,22,163,6,8,128,128,23,199,2,28, +248,22,148,7,23,194,2,9,249,22,80,23,195,1,27,249,22,163,6,8,128, +128,23,202,2,28,248,22,148,7,23,194,2,9,249,22,80,23,195,1,27,249, +22,163,6,8,128,128,23,205,2,28,248,22,148,7,23,194,2,9,249,22,80, +23,195,1,248,2,128,2,23,206,1,27,249,22,163,6,8,128,128,23,196,2, +28,248,22,142,8,23,194,2,28,249,22,132,4,248,22,147,8,23,196,2,8, +128,128,249,22,1,22,154,8,249,22,80,23,197,1,27,249,22,163,6,8,128, +128,23,201,2,28,248,22,148,7,23,194,2,9,249,22,80,23,195,1,27,249, +22,163,6,8,128,128,23,204,2,28,248,22,148,7,23,194,2,9,249,22,80, +23,195,1,27,249,22,163,6,8,128,128,23,207,2,28,248,22,148,7,23,194, +2,9,249,22,80,23,195,1,27,249,22,163,6,8,128,128,23,210,2,28,248, +22,148,7,23,194,2,9,249,22,80,23,195,1,248,2,128,2,23,211,1,192, +192,248,22,133,6,23,194,1,20,13,144,80,144,40,8,28,40,80,144,40,8, +46,42,27,28,249,22,189,8,248,22,180,8,2,62,41,90,144,42,11,89,146, +42,39,11,248,22,131,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22, +174,15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32, +0,88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248, +22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194, +2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8, +36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23, +197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22, +187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11, +9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95, +23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194, +2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248, +2,126,23,194,1,11,11,11,11,11,28,248,22,186,15,23,195,2,27,28,249, +22,189,8,248,22,180,8,2,62,41,249,22,145,6,23,197,2,32,0,88,148, +8,36,39,44,11,9,222,11,11,86,94,28,23,194,2,248,22,147,6,23,195, +1,86,94,23,194,1,12,249,22,80,27,248,22,188,5,23,199,1,250,22,44, +22,35,88,148,39,39,8,24,11,9,223,3,33,130,2,20,20,94,88,148,8, +36,39,46,11,9,223,3,33,131,2,23,196,1,194,249,22,80,11,194,28,28, +23,195,2,28,248,22,82,23,196,2,248,22,167,9,249,22,175,14,39,248,22, +164,20,23,199,2,11,11,194,86,94,23,195,1,249,22,12,20,20,94,88,148, +8,32,39,61,16,4,39,8,128,80,8,240,0,64,0,0,39,9,224,2,3, +33,132,2,23,196,1,80,144,41,8,26,41,27,248,22,167,9,194,28,192,192, +248,22,167,9,248,22,81,195,86,95,28,248,22,150,12,23,198,2,27,247,22, +142,12,28,249,22,132,12,23,195,2,2,63,251,22,138,12,23,197,1,2,63, +250,22,137,8,6,42,42,101,114,114,111,114,32,114,101,97,100,105,110,103,32, +99,111,108,108,101,99,116,105,111,110,32,108,105,110,107,115,32,102,105,108,101, +32,126,115,58,32,126,97,23,203,2,248,22,146,12,23,206,2,247,22,27,12, +12,28,23,193,2,250,22,156,2,80,144,45,8,25,41,23,198,1,249,22,80, +23,198,1,21,17,0,0,86,95,23,195,1,23,193,1,12,28,248,22,150,12, +23,198,2,86,94,23,197,1,248,23,195,1,247,22,138,2,196,88,148,39,40, +58,8,240,0,0,0,2,9,226,0,2,1,3,33,135,2,20,20,94,248,22, +148,6,23,194,2,28,248,22,148,7,248,22,148,6,23,195,1,12,248,22,177, +11,6,30,30,101,120,112,101,99,116,101,100,32,97,32,115,105,110,103,108,101, +32,83,45,101,120,112,114,101,115,115,105,111,110,248,22,133,6,23,194,1,28, +248,22,89,193,28,28,249,22,128,4,41,248,22,93,195,10,249,22,128,4,42, +248,22,93,195,28,28,248,22,153,7,248,22,81,194,10,28,249,22,169,9,2, +64,248,22,163,20,195,10,249,22,169,9,2,65,248,22,163,20,195,28,27,248, +22,102,194,28,248,22,174,15,193,10,28,248,22,153,7,193,28,248,22,133,16, +193,10,248,22,134,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22, +180,16,248,22,111,195,11,11,11,11,28,248,22,187,15,249,22,128,16,23,196, +2,23,198,2,27,248,22,68,248,22,178,15,23,198,1,250,22,156,2,23,198, +2,23,196,2,249,22,80,23,199,1,250,22,158,2,23,203,1,23,201,1,9, +12,250,22,156,2,23,197,1,23,198,1,249,22,80,23,198,1,23,201,1,28, +28,248,22,88,248,22,104,23,197,2,10,249,22,171,16,248,22,111,23,198,2, +247,22,171,8,27,248,22,138,16,249,22,136,16,248,22,102,23,200,2,23,198, +1,28,249,22,169,9,248,22,163,20,23,199,2,2,65,86,94,23,196,1,249, +22,3,20,20,94,88,148,8,36,40,56,11,9,224,3,2,33,140,2,23,196, +1,248,22,141,16,23,196,1,28,249,22,169,9,248,22,163,20,23,199,2,2, +64,86,94,23,196,1,86,94,28,250,22,158,2,23,197,2,11,11,12,250,22, +156,2,23,197,2,11,9,249,22,164,2,23,196,2,20,20,95,88,148,8,36, +41,53,11,9,224,3,2,33,141,2,23,195,1,23,196,1,27,248,22,68,248, +22,163,20,23,199,1,250,22,156,2,23,198,2,23,196,2,249,22,80,248,22, +129,2,23,200,1,250,22,158,2,23,203,1,23,201,1,9,12,250,22,156,2, +23,196,1,23,197,1,248,22,95,23,199,1,27,28,28,23,194,2,248,22,167, +9,248,22,81,23,196,2,10,9,27,249,22,188,5,23,198,2,68,98,105,110, +97,114,121,250,22,44,22,35,88,148,8,36,39,47,11,9,223,3,33,137,2, +20,20,94,88,148,8,36,39,46,11,9,223,3,33,138,2,23,196,1,86,94, +28,28,248,22,89,23,194,2,249,22,4,32,0,88,148,8,36,40,48,11,9, +222,33,139,2,23,195,2,11,12,248,22,177,11,6,18,18,105,108,108,45,102, +111,114,109,101,100,32,99,111,110,116,101,110,116,27,247,22,138,2,27,90,144, +42,11,89,146,42,39,11,248,22,131,16,23,201,2,192,86,96,249,22,3,20, +20,94,88,148,8,36,40,57,11,9,224,2,3,33,142,2,23,195,1,23,197, +1,249,22,164,2,195,88,148,8,36,41,51,11,9,223,3,33,143,2,250,22, +156,2,80,144,47,8,25,41,23,200,1,249,22,80,23,201,1,198,193,20,13, +144,80,144,40,8,28,40,250,80,144,43,8,47,42,23,198,2,23,196,2,11, +27,250,22,158,2,80,144,44,8,25,41,23,197,2,21,143,11,17,0,0,27, +248,22,81,23,195,2,27,249,80,144,45,8,27,42,23,198,2,23,196,2,28, +249,22,171,9,23,195,2,23,196,1,248,22,164,20,195,86,94,23,195,1,20, +13,144,80,144,43,8,28,40,250,80,144,46,8,47,42,23,201,1,23,199,2, +23,196,2,27,20,20,95,88,148,8,36,39,55,8,240,0,0,0,2,9,225, +5,4,1,33,144,2,23,194,1,23,197,1,28,249,22,48,23,195,2,39,20, +13,144,80,144,44,46,40,26,29,80,144,8,34,47,40,249,22,31,11,80,144, +8,36,46,40,22,144,15,10,22,145,15,10,22,146,15,10,22,149,15,10,22, +148,15,11,22,150,15,10,22,147,15,10,22,151,15,10,22,152,15,10,22,153, +15,10,22,154,15,10,22,155,15,11,22,156,15,10,22,142,15,11,247,23,193, +1,250,22,181,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39, +40,8,43,16,4,8,128,6,8,128,104,8,240,0,128,0,0,39,9,224,1, +2,33,145,2,23,195,1,0,7,35,114,120,34,47,43,34,28,248,22,153,7, +23,195,2,27,249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22, +128,4,248,22,101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22, +7,250,22,175,7,23,200,1,39,248,22,101,23,199,1,23,198,1,249,22,7, +250,22,175,7,23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7, +23,201,1,248,22,103,23,200,1,23,200,1,249,22,7,23,197,1,23,198,1, +90,144,42,11,89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1, +28,249,22,169,9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1, +23,200,1,27,249,22,80,23,197,1,23,201,1,28,248,22,153,7,23,195,2, +27,249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128,4,248, +22,101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7,250,22, +175,7,23,200,1,39,248,22,101,23,199,1,23,196,1,249,22,7,250,22,175, +7,23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23,201,1, +248,22,103,23,200,1,23,198,1,249,22,7,23,197,1,23,196,1,90,144,42, +11,89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1,28,249,22, +169,9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23,198,1, +249,80,144,48,8,31,42,194,249,22,80,197,199,28,248,22,88,23,196,2,9, +28,248,22,81,23,196,2,28,248,22,149,2,248,22,163,20,23,197,2,250,22, +94,249,22,2,22,129,2,250,22,158,2,248,22,163,20,23,204,2,23,202,2, +9,250,22,158,2,248,22,163,20,23,202,2,11,9,27,248,22,164,20,23,200, +1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2, +248,22,163,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248, +22,163,20,23,202,2,23,206,2,9,250,22,158,2,248,22,163,20,23,200,2, +11,9,249,80,144,48,8,48,42,23,203,1,248,22,164,20,23,199,1,27,248, +80,144,45,8,30,42,248,22,163,20,23,196,2,250,22,94,250,22,158,2,23, +199,2,23,205,2,9,250,22,158,2,23,199,1,11,9,249,80,144,49,8,48, +42,23,204,1,248,22,164,20,23,200,1,249,22,94,247,22,155,16,249,80,144, +47,8,48,42,23,202,1,248,22,164,20,23,198,1,27,248,80,144,41,8,30, +42,248,22,163,20,23,198,2,250,22,94,250,22,158,2,23,199,2,23,201,2, +9,250,22,158,2,23,199,1,11,9,27,248,22,164,20,23,201,1,28,248,22, +88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,163,20, +23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,163,20,23, +202,2,23,207,2,9,250,22,158,2,248,22,163,20,23,200,2,11,9,249,80, +144,49,8,48,42,23,204,1,248,22,164,20,23,199,1,27,248,80,144,46,8, +30,42,248,22,163,20,23,196,2,250,22,94,250,22,158,2,23,199,2,23,206, +2,9,250,22,158,2,23,199,1,11,9,249,80,144,50,8,48,42,23,205,1, +248,22,164,20,23,200,1,249,22,94,247,22,155,16,249,80,144,48,8,48,42, +23,203,1,248,22,164,20,23,198,1,249,22,94,247,22,155,16,27,248,22,164, +20,23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248, +22,149,2,248,22,163,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22, +158,2,248,22,163,20,23,202,2,23,205,2,9,250,22,158,2,248,22,163,20, +23,200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,164,20,23,199, +1,27,248,80,144,44,8,30,42,248,22,163,20,23,196,2,250,22,94,250,22, +158,2,23,199,2,23,204,2,9,250,22,158,2,23,199,1,11,9,249,80,144, +48,8,48,42,23,203,1,248,22,164,20,23,200,1,249,22,94,247,22,155,16, +249,80,144,46,8,48,42,23,201,1,248,22,164,20,23,198,1,32,150,2,88, +148,8,36,40,50,11,2,50,222,33,151,2,28,248,22,88,248,22,82,23,195, +2,248,22,90,27,248,22,163,20,195,28,248,22,174,15,193,248,22,178,15,193, +192,250,22,91,27,248,22,163,20,23,198,2,28,248,22,174,15,193,248,22,178, +15,193,192,2,67,248,2,150,2,248,22,164,20,23,198,1,250,22,137,8,6, +7,7,10,32,126,97,32,126,97,6,1,1,32,23,196,1,249,22,137,8,6, +6,6,10,32,32,32,126,97,248,22,132,2,23,196,1,32,154,2,88,148,39, +41,51,11,68,102,105,108,116,101,114,222,33,155,2,28,248,22,88,23,195,2, +9,28,248,23,194,2,248,22,81,23,196,2,249,22,80,248,22,163,20,23,197, +2,249,2,154,2,23,197,1,248,22,164,20,23,199,1,249,2,154,2,23,195, +1,248,22,164,20,23,197,1,28,248,22,88,23,201,2,86,95,23,200,1,23, +199,1,28,23,201,2,28,197,249,22,128,16,202,199,200,27,28,248,22,88,23, +198,2,2,66,249,22,1,22,176,7,248,2,150,2,23,200,2,248,23,199,1, +251,22,137,8,6,70,70,99,111,108,108,101,99,116,105,111,110,32,110,111,116, +32,102,111,117,110,100,10,32,32,99,111,108,108,101,99,116,105,111,110,58,32, +126,115,10,32,32,105,110,32,99,111,108,108,101,99,116,105,111,110,32,100,105, +114,101,99,116,111,114,105,101,115,58,126,97,126,97,28,248,22,88,23,203,1, +28,248,22,174,15,23,202,2,248,22,178,15,23,202,1,23,201,1,250,22,176, +7,28,248,22,174,15,23,205,2,248,22,178,15,23,205,1,23,204,1,2,67, +23,201,2,249,22,1,22,176,7,249,22,2,32,0,88,148,8,36,40,48,11, +9,222,33,152,2,27,248,22,93,23,206,2,27,248,22,93,247,22,155,16,28, +249,22,129,4,249,22,184,3,23,198,2,23,197,2,44,23,206,2,249,22,94, +247,22,155,16,248,22,90,249,22,137,8,6,50,50,46,46,46,32,91,126,97, +32,97,100,100,105,116,105,111,110,97,108,32,108,105,110,107,101,100,32,97,110, +100,32,112,97,99,107,97,103,101,32,100,105,114,101,99,116,111,114,105,101,115, +93,249,22,184,3,23,201,1,23,200,1,28,249,22,5,22,131,2,23,202,2, +250,22,137,8,6,49,49,10,32,32,32,115,117,98,45,99,111,108,108,101,99, +116,105,111,110,58,32,126,115,10,32,32,105,110,32,112,97,114,101,110,116,32, +100,105,114,101,99,116,111,114,105,101,115,58,126,97,23,201,1,249,22,1,22, +176,7,249,22,2,32,0,88,148,8,36,40,48,11,9,222,33,153,2,249,2, +154,2,22,131,2,23,209,1,86,95,23,200,1,23,198,1,2,66,27,248,22, +81,23,202,2,27,28,248,22,174,15,23,195,2,249,22,128,16,23,196,1,23, +199,2,248,22,132,2,23,195,1,28,28,248,22,174,15,248,22,163,20,23,204, +2,248,22,187,15,23,194,2,10,27,250,22,1,22,128,16,23,197,1,23,202, +2,28,28,248,22,88,23,200,2,10,248,22,187,15,23,194,2,28,23,201,2, +28,28,250,80,144,45,8,32,42,195,203,204,10,27,28,248,22,174,15,202,248, +22,178,15,202,201,19,248,22,156,7,23,195,2,27,28,249,22,132,4,23,196, +4,43,28,249,22,159,7,6,4,4,46,114,107,116,249,22,175,7,23,199,2, +249,22,184,3,23,200,4,43,249,22,176,7,250,22,175,7,23,200,1,39,249, +22,184,3,23,201,4,43,6,3,3,46,115,115,86,94,23,195,1,11,11,28, +23,193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249, +22,128,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16, +23,17,248,22,164,20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8, +49,42,204,205,206,23,15,23,16,23,17,248,22,164,20,23,19,23,19,26,8, +80,144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,164,20,23,18,23, +18,90,144,41,11,89,146,41,39,11,249,80,144,43,8,31,42,23,199,1,23, +200,1,27,248,22,68,28,248,22,174,15,195,248,22,178,15,195,194,27,27,247, +22,156,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22, +149,2,248,22,163,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158, +2,248,22,163,20,23,202,2,23,203,2,9,250,22,158,2,248,22,163,20,23, +200,2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,164,20,23,199,1, +27,248,80,144,46,8,30,42,248,22,163,20,23,196,2,250,22,94,250,22,158, +2,23,199,2,23,202,2,9,250,22,158,2,23,199,1,11,9,249,80,144,50, +8,48,42,23,201,1,248,22,164,20,23,200,1,249,22,94,247,22,155,16,249, +80,144,48,8,48,42,23,199,1,248,22,164,20,23,198,1,26,8,80,144,51, +8,49,42,200,202,203,205,23,16,23,17,200,11,32,158,2,88,148,8,36,42, +59,11,2,50,222,33,159,2,28,248,22,133,4,23,196,2,86,94,23,195,1, +19,248,22,147,8,23,195,2,19,248,22,147,8,23,196,2,249,22,184,15,27, +251,22,154,8,250,22,153,8,23,205,2,39,23,204,4,2,51,249,22,153,8, +23,204,1,23,202,4,2,68,28,248,22,133,4,248,22,147,8,23,195,2,86, +94,23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248,22,175,15, +198,248,22,176,15,198,247,22,177,15,2,2,27,248,22,182,3,23,197,1,28, +249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248,22,181,3, +23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23, +204,1,2,71,249,22,153,8,23,204,1,23,202,1,2,68,28,248,22,133,4, +248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2, +70,202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,250,2,158, +2,196,197,195,248,22,186,15,27,250,22,128,16,23,200,1,23,202,1,23,199, +1,28,249,22,169,9,23,197,2,66,115,97,109,101,192,28,248,22,133,16,23, +196,2,249,22,128,16,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249, +22,5,20,20,96,88,148,39,40,54,47,9,226,5,4,2,6,33,160,2,23, +199,1,23,195,1,23,197,1,23,196,1,27,248,22,186,15,249,22,128,16,23, +198,2,23,199,2,28,23,193,2,192,86,94,23,193,1,28,23,197,1,27,90, +144,41,11,89,146,41,39,11,250,80,144,46,8,34,42,23,202,2,2,68,2, +37,27,248,22,180,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248, +22,147,8,23,198,1,28,248,22,175,15,195,249,22,128,16,196,194,192,27,247, +22,157,16,249,22,5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3, +33,161,2,23,196,1,23,195,1,23,199,1,247,22,158,16,11,86,95,28,28, +248,22,175,15,23,194,2,10,28,248,22,174,15,23,194,2,10,28,248,22,153, +7,23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11, +12,252,22,181,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22, +153,7,23,195,2,10,248,22,142,8,23,195,2,86,94,23,194,1,12,252,22, +181,11,23,200,2,2,72,40,23,198,2,23,199,1,90,144,42,11,89,146,42, +39,11,248,22,131,16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86, +95,23,198,1,23,196,1,12,250,22,184,11,23,201,1,2,73,23,199,1,249, +22,7,23,195,1,23,196,1,32,164,2,88,148,8,36,46,61,11,2,74,222, +33,165,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2,39,23, +207,1,23,205,1,249,23,203,1,23,202,1,23,208,1,28,248,22,153,7,23, +204,2,249,22,168,8,23,205,1,8,63,23,203,1,28,248,22,133,4,248,22, +147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,201, +192,28,248,22,175,15,197,248,22,176,15,197,247,22,177,15,32,166,2,88,148, +8,36,45,8,24,11,2,50,222,33,167,2,28,248,22,133,4,23,199,2,86, +95,23,198,1,23,194,1,19,248,22,147,8,23,195,2,19,248,22,147,8,23, +196,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204, +4,2,51,249,23,206,1,23,204,1,23,202,4,28,248,22,153,7,23,207,2, +249,22,168,8,23,208,1,8,63,23,206,1,28,248,22,133,4,248,22,147,8, +23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,204,192,28, +248,22,175,15,200,248,22,176,15,200,247,22,177,15,2,2,27,248,22,182,3, +23,200,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27, +248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23, +205,2,39,23,204,1,23,203,1,249,23,206,1,23,204,1,23,202,1,28,248, +22,153,7,23,207,2,249,22,168,8,23,208,1,8,63,23,206,1,28,248,22, 133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2, -69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199,247,22,177,15,251, -2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248, -22,175,15,23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153,7, -23,196,2,28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,12, -252,22,181,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7, -23,197,2,10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72,40, -23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,199, -2,86,94,23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23,201, -2,249,22,7,194,195,27,248,22,180,15,23,196,1,27,251,2,169,2,23,198, -2,23,201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195,249, -22,128,16,196,194,192,2,51,252,80,144,44,8,35,42,2,37,2,51,32,0, -88,148,8,36,41,46,11,9,222,33,172,2,198,199,32,174,2,88,148,8,36, -43,60,11,2,50,222,33,177,2,32,175,2,88,148,8,36,45,60,11,2,74, -222,33,176,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2,39, -23,206,1,23,204,1,249,22,153,8,23,202,1,23,207,1,28,248,22,153,7, -23,203,2,249,22,168,8,23,204,1,8,63,23,202,1,28,248,22,133,4,248, +69,2,70,204,192,28,248,22,175,15,200,248,22,176,15,200,247,22,177,15,28, +248,22,133,4,23,194,2,86,95,23,195,1,23,193,1,19,248,22,147,8,23, +196,2,19,248,22,147,8,23,197,2,249,22,184,15,27,251,22,154,8,250,22, +153,8,23,206,2,39,23,204,4,2,51,249,23,207,1,23,205,1,23,202,4, +28,248,22,153,7,23,208,2,249,22,168,8,23,209,1,8,63,23,207,1,28, +248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2, +37,2,69,2,70,205,192,28,248,22,175,15,201,248,22,176,15,201,247,22,177, +15,2,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148, +8,23,199,2,23,197,2,27,248,22,181,3,23,195,2,249,22,184,15,27,251, +22,154,8,250,22,153,8,23,206,2,39,23,204,1,23,204,1,249,23,207,1, +23,205,1,23,202,1,28,248,22,153,7,23,208,2,249,22,168,8,23,209,1, +8,63,23,207,1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193, +1,251,22,183,11,2,37,2,69,2,70,205,192,28,248,22,175,15,201,248,22, +176,15,201,247,22,177,15,28,248,22,133,4,193,254,2,164,2,201,203,204,205, +248,22,147,8,202,2,51,248,22,147,8,202,27,248,22,182,3,194,28,249,22, +169,9,8,46,249,22,148,8,199,196,254,2,164,2,202,204,205,206,199,203,248, +22,181,3,200,253,2,166,2,201,202,203,204,205,198,90,144,41,11,89,146,41, +39,11,86,95,28,28,248,22,175,15,23,199,2,10,28,248,22,174,15,23,199, +2,10,28,248,22,153,7,23,199,2,28,248,22,133,16,23,199,2,10,248,22, +134,16,23,199,2,11,12,252,22,181,11,23,200,2,2,42,39,23,203,2,23, +204,2,28,28,248,22,153,7,23,200,2,10,248,22,142,8,23,200,2,12,252, +22,181,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146, +42,39,11,248,22,131,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250, +22,184,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,180,15, +23,196,1,27,19,248,22,147,8,23,196,2,28,248,22,133,4,23,194,4,86, +94,23,199,1,19,248,22,147,8,23,197,2,19,248,22,147,8,23,198,2,249, +22,184,15,27,251,22,154,8,250,22,153,8,23,207,2,39,23,204,4,2,51, +249,23,211,1,23,206,1,23,202,4,28,248,22,153,7,23,212,2,249,22,168, +8,23,213,1,8,63,23,211,1,28,248,22,133,4,248,22,147,8,23,195,2, +86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,23,17,192,28,248,22, +175,15,205,248,22,176,15,205,247,22,177,15,2,2,27,248,22,182,3,23,195, +4,28,249,22,169,9,8,46,249,22,148,8,23,200,2,23,197,2,27,248,22, +181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,207,2, +39,23,204,1,23,208,1,249,23,211,1,23,206,1,23,202,1,28,248,22,153, +7,23,212,2,249,22,168,8,23,213,1,8,63,23,211,1,28,248,22,133,4, +248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2, +70,23,17,192,28,248,22,175,15,205,248,22,176,15,205,247,22,177,15,28,248, +22,133,4,23,194,2,86,95,23,200,1,23,193,1,254,2,164,2,23,203,2, +23,208,1,23,209,1,23,210,1,248,22,147,8,23,204,2,2,51,248,22,147, +8,23,204,1,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22, +148,8,23,201,2,23,197,2,254,2,164,2,23,204,1,23,209,1,23,210,1, +23,211,1,23,200,2,23,208,1,248,22,181,3,23,201,1,253,2,166,2,23, +203,1,23,207,1,23,208,1,23,209,1,23,210,1,23,199,1,2,28,248,22, +175,15,195,249,22,128,16,196,194,192,32,169,2,88,148,8,36,43,61,11,2, +50,222,33,170,2,28,248,22,133,4,23,197,2,86,94,23,196,1,19,248,22, +147,8,23,195,2,35,248,22,147,8,23,196,2,249,22,184,15,27,251,22,154, +8,250,22,153,8,23,205,1,39,23,204,4,2,51,2,51,28,248,22,153,7, +23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248, 22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, -200,192,28,248,22,175,15,196,248,22,176,15,196,247,22,177,15,28,248,22,133, -4,23,197,2,86,94,23,196,1,19,248,22,147,8,23,195,2,19,248,22,147, -8,23,196,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39, -23,204,4,2,51,249,22,153,8,23,204,1,23,202,4,28,248,22,153,7,23, -205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22, -147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202, -192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,2,27,248,22, +202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,27,248,22, 182,3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197, -2,27,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153, -8,23,205,2,39,23,204,1,2,71,249,22,153,8,23,204,1,23,202,1,28, -248,22,153,7,23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248, +2,35,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153, +8,23,205,1,39,23,204,1,2,51,2,51,28,248,22,153,7,23,205,2,249, +22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22,147,8,23, +195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248, +22,175,15,198,248,22,176,15,198,247,22,177,15,28,248,22,133,4,23,194,2, +86,94,23,193,1,19,248,22,147,8,23,196,2,35,248,22,147,8,23,197,2, +249,22,184,15,27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,4,2, +51,2,51,28,248,22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23, +205,1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22, +183,11,2,37,2,69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199, +247,22,177,15,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249, +22,148,8,23,199,2,23,197,2,35,248,22,181,3,23,195,2,249,22,184,15, +27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,1,2,51,2,51,28, +248,22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205,1,28,248, 22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37, -2,69,2,70,202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15, -28,248,22,133,4,193,253,2,175,2,199,200,201,248,22,147,8,200,2,51,248, -22,147,8,200,27,248,22,182,3,194,28,249,22,169,9,8,46,249,22,148,8, -198,196,253,2,175,2,200,201,202,198,2,71,248,22,181,3,199,251,2,174,2, -198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,175,15, -23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2, -28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,12,252,22,181, -11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7,23,197,2, -10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72,40,23,200,2, -23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,199,2,86,94, -23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23,201,2,249,22, -7,194,195,27,248,22,180,15,23,196,1,27,251,2,174,2,23,198,2,23,201, -1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195,249,22,128,16, -196,194,192,252,80,144,44,8,35,42,2,37,2,71,22,153,8,198,199,249,247, -22,176,5,23,195,1,11,249,247,22,176,5,194,11,28,248,22,88,23,195,2, -9,27,27,248,22,81,23,197,2,28,248,22,135,16,23,194,2,248,22,138,16, -23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248, -22,131,16,249,22,136,16,250,80,144,50,43,42,248,22,151,16,2,56,11,11, -248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136, -16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,151,16,2,56,23, -197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28,23,193,2,249,22, -80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,27,248,22,163,20, -23,199,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81, -23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1, -247,22,152,16,248,80,144,47,8,50,42,248,22,163,20,23,198,1,86,94,23, -193,1,248,80,144,45,8,50,42,248,22,163,20,23,196,1,86,94,23,193,1, -27,248,22,163,20,23,197,1,28,248,22,88,23,194,2,9,27,248,80,144,43, -56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22, -136,16,23,198,1,247,22,152,16,248,80,144,45,8,50,42,248,22,163,20,23, -198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,163,20,23,196,1, +2,69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199,247,22,177,15, +251,2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28, +248,22,175,15,23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153, +7,23,196,2,28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11, +12,252,22,181,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153, +7,23,197,2,10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72, +40,23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23, +199,2,86,94,23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23, +201,2,249,22,7,194,195,27,248,22,180,15,23,196,1,27,251,2,169,2,23, +198,2,23,201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195, +249,22,128,16,196,194,192,2,51,252,80,144,44,8,35,42,2,37,2,51,32, +0,88,148,8,36,41,46,11,9,222,33,172,2,198,199,32,174,2,88,148,8, +36,43,60,11,2,50,222,33,177,2,32,175,2,88,148,8,36,45,60,11,2, +74,222,33,176,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2, +39,23,206,1,23,204,1,249,22,153,8,23,202,1,23,207,1,28,248,22,153, +7,23,203,2,249,22,168,8,23,204,1,8,63,23,202,1,28,248,22,133,4, +248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2, +70,200,192,28,248,22,175,15,196,248,22,176,15,196,247,22,177,15,28,248,22, +133,4,23,197,2,86,94,23,196,1,19,248,22,147,8,23,195,2,19,248,22, +147,8,23,196,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2, +39,23,204,4,2,51,249,22,153,8,23,204,1,23,202,4,28,248,22,153,7, +23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248, +22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, +202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,2,27,248, +22,182,3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23, +197,2,27,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22, +153,8,23,205,2,39,23,204,1,2,71,249,22,153,8,23,204,1,23,202,1, +28,248,22,153,7,23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28, +248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2, +37,2,69,2,70,202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177, +15,28,248,22,133,4,193,253,2,175,2,199,200,201,248,22,147,8,200,2,51, +248,22,147,8,200,27,248,22,182,3,194,28,249,22,169,9,8,46,249,22,148, +8,198,196,253,2,175,2,200,201,202,198,2,71,248,22,181,3,199,251,2,174, +2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,175, +15,23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196, +2,28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,12,252,22, +181,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7,23,197, +2,10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72,40,23,200, +2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,199,2,86, +94,23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23,201,2,249, +22,7,194,195,27,248,22,180,15,23,196,1,27,251,2,174,2,23,198,2,23, +201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195,249,22,128, +16,196,194,192,252,80,144,44,8,35,42,2,37,2,71,22,153,8,198,199,249, +247,22,176,5,23,195,1,11,249,247,22,176,5,194,11,28,248,22,88,23,195, +2,9,27,27,248,22,81,23,197,2,28,248,22,135,16,23,194,2,248,22,138, +16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11, +248,22,131,16,249,22,136,16,250,80,144,50,43,42,248,22,151,16,2,56,11, +11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22, +136,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,151,16,2,56, +23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28,23,193,2,249, +22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,27,248,22,164, +20,23,199,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22, +81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198, +1,247,22,152,16,248,80,144,47,8,50,42,248,22,164,20,23,198,1,86,94, +23,193,1,248,80,144,45,8,50,42,248,22,164,20,23,196,1,86,94,23,193, +1,27,248,22,164,20,23,197,1,28,248,22,88,23,194,2,9,27,248,80,144, +43,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249, +22,136,16,23,198,1,247,22,152,16,248,80,144,45,8,50,42,248,22,164,20, +23,198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,164,20,23,196, +1,28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,135, +16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144, +42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,50,43,42, +248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194, +1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,45,43, +42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194, +1,11,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247, +22,152,16,27,248,22,164,20,23,199,1,28,248,22,88,23,194,2,9,27,248, +80,144,45,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138, +16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,47,8,51,42,248,22, +164,20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,164,20, +23,196,1,86,94,23,193,1,27,248,22,164,20,23,197,1,28,248,22,88,23, +194,2,9,27,248,80,144,43,56,42,248,22,81,23,196,2,28,23,193,2,249, +22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,45, +8,51,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51, +42,248,22,164,20,23,196,1,27,248,22,151,16,2,58,28,248,22,135,16,23, +194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11, +89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22, +151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248, +22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248, +22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11, 28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,135,16, 23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42, 11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,50,43,42,248, @@ -844,730 +865,709 @@ 248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,45,43,42, 248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1, 11,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22, -152,16,27,248,22,163,20,23,199,1,28,248,22,88,23,194,2,9,27,248,80, -144,45,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138,16, -249,22,136,16,23,198,1,247,22,152,16,248,80,144,47,8,51,42,248,22,163, -20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,163,20,23, -196,1,86,94,23,193,1,27,248,22,163,20,23,197,1,28,248,22,88,23,194, -2,9,27,248,80,144,43,56,42,248,22,81,23,196,2,28,23,193,2,249,22, -80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,45,8, -51,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51,42, -248,22,163,20,23,196,1,27,248,22,151,16,2,58,28,248,22,135,16,23,194, -2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89, -146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22,151, -16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22, -138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, -151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28, -248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,135,16,23, -194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11, -89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,50,43,42,248,22, -151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248, -22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248, -22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11, -28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152, -16,27,248,22,163,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248,22, +152,16,27,248,22,164,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248, +22,81,23,196,2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28, +248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249, +22,136,16,250,80,144,54,43,42,248,22,151,16,2,56,11,11,248,22,151,16, +2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1, +23,196,1,27,250,80,144,49,43,42,248,22,151,16,2,56,23,197,1,10,28, +23,193,2,248,22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138, +16,249,22,136,16,23,198,1,247,22,152,16,27,248,22,164,20,23,198,1,28, +248,22,88,23,194,2,9,27,248,80,144,49,56,42,248,22,81,23,196,2,28, +23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16, +248,80,144,51,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80, +144,49,8,53,42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164, +20,23,196,1,28,248,22,88,23,194,2,9,27,248,80,144,47,56,42,248,22, +81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198, +1,247,22,152,16,248,80,144,49,8,53,42,248,22,164,20,23,198,1,86,94, +23,193,1,248,80,144,47,8,53,42,248,22,164,20,23,196,1,86,94,23,193, +1,27,248,22,164,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22, 81,23,196,2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248, 22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22, -136,16,250,80,144,54,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2, +136,16,250,80,144,52,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2, 57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23, -196,1,27,250,80,144,49,43,42,248,22,151,16,2,56,23,197,1,10,28,23, +196,1,27,250,80,144,47,43,42,248,22,151,16,2,56,23,197,1,10,28,23, 193,2,248,22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16, -249,22,136,16,23,198,1,247,22,152,16,27,248,22,163,20,23,198,1,28,248, -22,88,23,194,2,9,27,248,80,144,49,56,42,248,22,81,23,196,2,28,23, +249,22,136,16,23,198,1,247,22,152,16,27,248,22,164,20,23,198,1,28,248, +22,88,23,194,2,9,27,248,80,144,47,56,42,248,22,81,23,196,2,28,23, 193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248, -80,144,51,8,53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144, -49,8,53,42,248,22,163,20,23,196,1,86,94,23,193,1,27,248,22,163,20, -23,196,1,28,248,22,88,23,194,2,9,27,248,80,144,47,56,42,248,22,81, +80,144,49,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144, +47,8,53,42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164,20, +23,196,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81, 23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1, -247,22,152,16,248,80,144,49,8,53,42,248,22,163,20,23,198,1,86,94,23, -193,1,248,80,144,47,8,53,42,248,22,163,20,23,196,1,86,94,23,193,1, -27,248,22,163,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22,81, -23,196,2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22, -134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136, -16,250,80,144,52,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57, -86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196, -1,27,250,80,144,47,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193, -2,248,22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16,249, -22,136,16,23,198,1,247,22,152,16,27,248,22,163,20,23,198,1,28,248,22, -88,23,194,2,9,27,248,80,144,47,56,42,248,22,81,23,196,2,28,23,193, -2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80, -144,49,8,53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144,47, -8,53,42,248,22,163,20,23,196,1,86,94,23,193,1,27,248,22,163,20,23, -196,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81,23, -196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247, -22,152,16,248,80,144,47,8,53,42,248,22,163,20,23,198,1,86,94,23,193, -1,248,80,144,45,8,53,42,248,22,163,20,23,196,1,27,247,22,159,16,27, -248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44,41,28,23,196, -2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63, -2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1, -250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247,22, -171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,50,42,250,22,94, -9,248,22,90,248,22,151,16,2,55,9,28,193,249,22,80,195,194,192,27,247, -22,159,16,27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44, -41,28,23,196,2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165, -8,194,7,63,2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27, -28,23,200,1,250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205,1, -2,59,247,22,171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,51, -42,250,22,94,23,207,1,248,22,90,248,22,151,16,2,55,9,28,193,249,22, -80,195,194,192,27,247,22,159,16,27,248,80,144,42,58,42,249,80,144,44,55, -40,40,80,144,44,8,52,42,249,80,144,43,44,41,28,23,196,2,27,249,22, -175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63,2,66,2,66, -250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1,250,22,128,16, -248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247,22,171,8,2,77, -86,94,23,199,1,11,27,27,250,22,94,23,207,1,248,22,90,248,22,151,16, -2,55,23,208,1,28,248,22,88,23,194,2,9,27,27,248,22,81,23,196,2, -28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23, -194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80, -144,60,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23, -195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250, -80,144,55,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22, -138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16, -23,198,1,247,22,152,16,27,248,22,163,20,23,198,1,28,248,22,88,23,194, -2,9,27,248,80,144,55,56,42,248,22,81,23,196,2,28,23,193,2,249,22, -80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,57,8, -53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53,42, -248,22,163,20,23,196,1,86,94,23,193,1,27,248,22,163,20,23,196,1,28, -248,22,88,23,194,2,9,27,248,80,144,53,56,42,248,22,81,23,196,2,28, -23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16, -248,80,144,55,8,53,42,248,22,163,20,23,198,1,86,94,23,193,1,248,80, -144,53,8,53,42,248,22,163,20,23,196,1,28,193,249,22,80,195,194,192,27, -20,13,144,80,144,40,46,40,26,9,80,144,49,47,40,249,22,31,11,80,144, -51,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157,15,10,248,22, -148,6,23,196,2,28,248,22,148,7,23,194,2,12,86,94,248,22,177,9,23, -194,1,27,20,13,144,80,144,41,46,40,26,9,80,144,50,47,40,249,22,31, -11,80,144,52,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157,15, -10,248,22,148,6,23,197,2,28,248,22,148,7,23,194,2,12,86,94,248,22, -177,9,23,194,1,27,20,13,144,80,144,42,46,40,26,9,80,144,51,47,40, -249,22,31,11,80,144,53,46,40,22,148,15,10,22,155,15,10,22,156,15,10, -22,157,15,10,248,22,148,6,23,198,2,28,248,22,148,7,23,194,2,12,86, -94,248,22,177,9,23,194,1,248,80,144,43,8,54,42,197,86,94,249,22,139, -7,247,22,172,5,23,196,2,248,22,163,6,249,22,136,4,39,249,22,184,3, -28,23,198,2,23,198,1,86,94,23,198,1,39,23,199,1,27,248,22,189,5, -28,23,198,2,86,95,23,197,1,23,196,1,23,198,1,86,94,23,198,1,27, -250,80,144,45,43,42,248,22,151,16,2,56,11,11,27,248,22,139,4,23,199, -1,27,28,23,194,2,23,194,1,86,94,23,194,1,39,27,248,22,139,4,23, -202,1,249,22,140,6,23,198,1,20,20,95,88,148,8,36,39,51,11,9,224, -3,2,33,190,2,23,195,1,23,196,1,248,80,144,41,8,54,42,193,144,39, -20,121,145,2,1,39,16,1,11,16,0,20,27,15,56,9,2,2,2,2,29, -11,11,11,11,11,11,11,9,9,11,11,11,10,46,80,143,39,39,20,121,145, -2,1,54,16,40,2,3,2,4,2,5,2,6,2,7,2,8,2,9,30,2, -11,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107, -101,121,11,6,30,2,11,1,23,101,120,116,101,110,100,45,112,97,114,97,109, -101,116,101,114,105,122,97,116,105,111,110,11,4,2,12,2,13,2,14,2,15, -2,16,2,17,2,18,30,2,11,1,19,99,97,99,104,101,45,99,111,110,102, -105,103,117,114,97,116,105,111,110,11,1,2,19,2,20,2,21,2,22,2,23, -2,24,2,25,2,26,2,27,2,28,2,29,30,2,11,1,21,101,120,99,101, -112,116,105,111,110,45,104,97,110,100,108,101,114,45,107,101,121,11,3,2,30, -2,31,2,32,2,33,2,34,2,35,2,36,2,37,2,38,2,39,2,40,16, -0,40,42,39,16,0,39,16,19,2,13,2,14,2,12,2,25,2,4,2,35, -2,23,2,24,2,19,2,29,2,33,2,21,2,22,2,31,2,27,2,30,2, -32,2,36,2,28,58,11,11,11,16,17,2,9,2,17,2,15,2,40,2,16, -2,7,2,26,2,39,2,18,2,20,2,38,2,5,2,34,2,8,2,37,2, -3,2,6,16,17,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, -11,16,17,2,9,2,17,2,15,2,40,2,16,2,7,2,26,2,39,2,18, -2,20,2,38,2,5,2,34,2,8,2,37,2,3,2,6,56,56,40,12,11, -11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39, -16,51,20,15,16,2,32,0,88,148,8,36,40,48,11,2,3,222,33,78,80, -144,39,39,40,20,15,16,2,249,22,155,7,7,92,7,92,80,144,39,40,40, -20,15,16,2,88,148,8,36,40,57,41,2,5,223,0,33,83,80,144,39,41, -40,20,15,16,2,88,148,8,36,41,61,41,2,6,223,0,33,85,80,144,39, -42,40,20,15,16,2,20,26,96,2,7,88,148,8,36,42,8,24,8,32,9, -223,0,33,92,88,148,8,36,41,50,55,9,223,0,33,93,88,148,8,36,40, -49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,163,16, -248,22,167,8,27,28,249,22,169,9,247,22,180,8,2,43,6,1,1,59,6, -1,1,58,250,22,137,8,6,14,14,40,91,94,126,97,93,42,41,126,97,40, -46,42,41,23,196,2,23,196,1,88,148,8,36,41,51,11,2,8,223,0,33, -98,80,144,39,44,40,20,15,16,2,88,148,39,40,8,38,8,128,6,2,9, -223,0,33,99,80,144,39,45,40,20,15,16,2,32,0,88,148,8,36,41,50, -11,2,12,222,33,100,80,144,39,48,40,20,15,16,2,32,0,88,148,8,36, -42,51,11,2,13,222,33,102,80,144,39,49,40,20,15,16,2,32,0,88,148, -8,36,41,49,11,2,14,222,33,103,80,144,39,50,40,20,15,16,2,88,148, -39,42,53,8,128,128,2,15,223,0,33,105,80,144,39,51,40,20,15,16,2, -88,148,39,44,55,8,128,128,2,17,223,0,33,107,80,144,39,53,40,20,15, -16,2,88,148,39,39,56,55,9,223,0,33,108,80,144,39,8,40,42,20,15, -16,2,88,148,39,39,47,16,4,39,40,8,128,4,39,2,18,223,0,33,109, -80,144,39,54,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,110,80, -144,39,8,41,42,20,15,16,2,88,148,39,39,47,16,4,39,40,8,128,8, -39,2,20,223,0,33,111,80,144,39,57,40,20,15,16,2,88,148,8,36,39, -8,38,8,128,6,9,223,0,33,112,80,144,39,8,42,42,20,15,16,2,88, -148,8,36,40,50,16,4,39,39,8,128,16,39,2,21,223,0,33,113,80,144, -39,58,40,20,15,16,2,20,28,143,32,0,88,148,39,40,48,11,2,22,222, -33,114,32,0,88,148,39,40,48,11,2,22,222,33,115,80,144,39,59,40,20, -15,16,2,88,148,8,36,40,50,8,240,0,128,0,0,2,23,223,0,33,116, -80,144,39,60,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,117,80, -144,39,8,43,42,20,15,16,2,88,148,8,36,40,51,16,4,39,40,8,128, -32,39,2,24,223,0,33,118,80,144,39,61,40,20,15,16,2,88,148,39,40, -56,55,2,19,223,0,33,119,80,144,39,56,40,20,15,16,2,88,148,8,36, -41,58,16,4,8,240,0,128,0,0,8,32,8,128,64,39,2,50,223,0,33, -120,80,144,39,8,44,42,20,15,16,2,88,148,8,36,42,52,16,4,39,39, -8,128,64,39,2,25,223,0,33,121,80,144,39,8,23,40,20,15,16,2,88, -148,39,39,56,55,9,223,0,33,122,80,144,39,8,45,42,20,15,16,2,88, -148,8,36,39,57,16,4,8,240,0,128,0,0,8,137,2,8,128,128,39,2, -26,223,0,33,123,80,144,39,8,24,40,20,15,16,2,247,22,140,2,80,144, -39,8,25,40,20,15,16,2,248,22,16,67,115,116,97,109,112,80,144,39,8, -26,40,20,15,16,2,88,148,39,40,49,8,240,0,0,0,4,9,223,0,33, -125,80,144,39,8,46,42,20,15,16,2,88,148,39,41,51,16,4,39,8,128, -80,8,240,0,64,0,0,39,2,29,223,0,33,133,2,80,144,39,8,27,40, -20,15,16,2,32,0,88,148,8,36,40,48,11,2,30,222,33,134,2,80,144, -39,8,29,40,20,15,16,2,88,148,8,36,42,48,8,240,0,0,0,2,74, -109,97,107,101,45,104,97,110,100,108,101,114,223,0,33,136,2,80,144,39,8, -47,42,20,15,16,2,88,148,39,40,47,16,4,8,128,6,8,128,104,8,240, -0,128,0,0,39,2,31,223,0,33,146,2,80,144,39,8,30,40,20,15,16, -2,88,148,39,41,59,16,2,39,8,240,0,128,0,0,2,32,223,0,33,148, -2,80,144,39,8,31,40,20,15,16,2,88,148,8,36,41,61,16,4,39,8, -240,0,64,0,0,39,40,2,50,223,0,33,149,2,80,144,39,8,48,42,20, -15,16,2,88,148,39,47,8,33,16,4,39,39,40,41,67,99,108,111,111,112, -223,0,33,156,2,80,144,39,8,49,42,20,15,16,2,88,148,39,44,8,25, -16,4,39,8,240,0,192,0,0,39,42,2,16,223,0,33,157,2,80,144,39, -52,40,20,15,16,2,88,148,39,42,58,16,4,47,39,43,39,2,33,223,0, -33,162,2,80,144,39,8,32,40,20,15,16,2,32,0,88,148,39,42,53,11, -2,35,222,33,163,2,80,144,39,8,34,40,20,15,16,2,32,0,88,148,8, -36,44,8,27,11,2,36,222,33,168,2,80,144,39,8,35,40,20,15,16,2, -20,28,143,32,0,88,148,8,36,41,55,11,2,37,222,33,171,2,88,148,8, -100,41,52,16,4,39,39,47,39,2,37,223,0,33,173,2,80,144,39,8,36, -40,20,15,16,2,20,28,143,32,0,88,148,8,36,41,55,11,2,34,222,33, -178,2,88,148,8,100,41,52,16,4,39,39,47,39,2,34,223,0,33,179,2, -80,144,39,8,33,40,20,15,16,2,20,28,143,32,0,88,148,39,40,47,11, -2,38,222,33,180,2,32,0,88,148,39,40,47,11,2,38,222,33,181,2,80, -144,39,8,37,40,20,15,16,2,88,148,8,36,40,58,16,4,55,41,39,43, -2,50,223,0,33,182,2,80,144,39,8,50,42,20,15,16,2,88,148,8,36, -40,58,16,4,55,41,39,47,2,50,223,0,33,183,2,80,144,39,8,51,42, -20,15,16,2,88,148,39,39,56,55,9,223,0,33,184,2,80,144,39,8,52, -42,20,15,16,2,88,148,8,36,40,8,23,16,4,55,41,39,8,32,2,50, -223,0,33,185,2,80,144,39,8,53,42,20,15,16,2,20,26,96,2,39,88, -148,39,39,60,16,4,8,32,8,140,2,39,43,9,223,0,33,186,2,88,148, -39,40,61,16,4,8,32,8,140,2,39,47,9,223,0,33,187,2,88,148,39, -41,8,30,16,4,8,48,8,139,2,39,8,48,9,223,0,33,188,2,80,144, -39,8,38,40,20,15,16,2,88,148,8,36,40,60,16,4,8,128,6,39,39, -8,64,2,50,223,0,33,189,2,80,144,39,8,54,42,20,15,16,2,88,148, -8,36,42,56,16,4,55,39,39,8,64,2,40,223,0,33,191,2,80,144,39, -8,39,40,95,29,94,2,10,70,35,37,107,101,114,110,101,108,11,29,94,2, -10,71,35,37,109,105,110,45,115,116,120,11,2,11,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 19759); +247,22,152,16,248,80,144,47,8,53,42,248,22,164,20,23,198,1,86,94,23, +193,1,248,80,144,45,8,53,42,248,22,164,20,23,196,1,27,247,22,159,16, +27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44,41,28,23, +196,2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7, +63,2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200, +1,250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247, +22,171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,50,42,250,22, +94,9,248,22,90,248,22,151,16,2,55,9,28,193,249,22,80,195,194,192,27, +247,22,159,16,27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43, +44,41,28,23,196,2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22, +165,8,194,7,63,2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76, +27,28,23,200,1,250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205, +1,2,59,247,22,171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8, +51,42,250,22,94,23,207,1,248,22,90,248,22,151,16,2,55,9,28,193,249, +22,80,195,194,192,27,247,22,159,16,27,248,80,144,42,58,42,249,80,144,44, +55,40,40,80,144,44,8,52,42,249,80,144,43,44,41,28,23,196,2,27,249, +22,175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63,2,66,2, +66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1,250,22,128, +16,248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247,22,171,8,2, +77,86,94,23,199,1,11,27,27,250,22,94,23,207,1,248,22,90,248,22,151, +16,2,55,23,208,1,28,248,22,88,23,194,2,9,27,27,248,22,81,23,196, +2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16, +23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250, +80,144,60,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95, +23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27, +250,80,144,55,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248, +22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16,249,22,136, +16,23,198,1,247,22,152,16,27,248,22,164,20,23,198,1,28,248,22,88,23, +194,2,9,27,248,80,144,55,56,42,248,22,81,23,196,2,28,23,193,2,249, +22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,57, +8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53, +42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164,20,23,196,1, +28,248,22,88,23,194,2,9,27,248,80,144,53,56,42,248,22,81,23,196,2, +28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152, +16,248,80,144,55,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248, +80,144,53,8,53,42,248,22,164,20,23,196,1,28,193,249,22,80,195,194,192, +27,20,13,144,80,144,40,46,40,26,9,80,144,49,47,40,249,22,31,11,80, +144,51,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157,15,10,248, +22,148,6,23,196,2,28,248,22,148,7,23,194,2,12,86,94,248,22,177,9, +23,194,1,27,20,13,144,80,144,41,46,40,26,9,80,144,50,47,40,249,22, +31,11,80,144,52,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157, +15,10,248,22,148,6,23,197,2,28,248,22,148,7,23,194,2,12,86,94,248, +22,177,9,23,194,1,27,20,13,144,80,144,42,46,40,26,9,80,144,51,47, +40,249,22,31,11,80,144,53,46,40,22,148,15,10,22,155,15,10,22,156,15, +10,22,157,15,10,248,22,148,6,23,198,2,28,248,22,148,7,23,194,2,12, +86,94,248,22,177,9,23,194,1,248,80,144,43,8,54,42,197,86,94,249,22, +139,7,247,22,172,5,23,196,2,248,22,163,6,249,22,136,4,39,249,22,184, +3,28,23,198,2,23,198,1,86,94,23,198,1,39,23,199,1,27,248,22,189, +5,28,23,198,2,86,95,23,197,1,23,196,1,23,198,1,86,94,23,198,1, +27,250,80,144,45,43,42,248,22,151,16,2,56,11,11,27,248,22,139,4,23, +199,1,27,28,23,194,2,23,194,1,86,94,23,194,1,39,27,248,22,139,4, +23,202,1,249,22,140,6,23,198,1,20,20,95,88,148,8,36,39,51,11,9, +224,3,2,33,190,2,23,195,1,23,196,1,248,80,144,41,8,54,42,193,144, +39,20,121,145,2,1,39,16,1,11,16,0,20,27,15,56,9,2,2,2,2, +29,11,11,11,11,11,11,11,9,9,11,11,11,10,46,80,143,39,39,20,121, +145,2,1,54,16,40,2,3,2,4,2,5,2,6,2,7,2,8,2,9,30, +2,11,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,45, +107,101,121,11,6,30,2,11,1,23,101,120,116,101,110,100,45,112,97,114,97, +109,101,116,101,114,105,122,97,116,105,111,110,11,4,2,12,2,13,2,14,2, +15,2,16,2,17,2,18,30,2,11,1,19,99,97,99,104,101,45,99,111,110, +102,105,103,117,114,97,116,105,111,110,11,1,2,19,2,20,2,21,2,22,2, +23,2,24,2,25,2,26,2,27,2,28,2,29,30,2,11,1,21,101,120,99, +101,112,116,105,111,110,45,104,97,110,100,108,101,114,45,107,101,121,11,3,2, +30,2,31,2,32,2,33,2,34,2,35,2,36,2,37,2,38,2,39,2,40, +16,0,40,42,39,16,0,39,16,19,2,13,2,14,2,12,2,25,2,4,2, +35,2,23,2,24,2,19,2,29,2,33,2,21,2,22,2,31,2,27,2,30, +2,32,2,36,2,28,58,11,11,11,16,17,2,9,2,17,2,15,2,40,2, +16,2,7,2,26,2,39,2,18,2,20,2,38,2,5,2,34,2,8,2,37, +2,3,2,6,16,17,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +11,11,16,17,2,9,2,17,2,15,2,40,2,16,2,7,2,26,2,39,2, +18,2,20,2,38,2,5,2,34,2,8,2,37,2,3,2,6,56,56,40,12, +11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39, +39,16,51,20,15,16,2,32,0,88,148,8,36,40,48,11,2,3,222,33,78, +80,144,39,39,40,20,15,16,2,249,22,155,7,7,92,7,92,80,144,39,40, +40,20,15,16,2,88,148,8,36,40,57,41,2,5,223,0,33,83,80,144,39, +41,40,20,15,16,2,88,148,8,36,41,61,41,2,6,223,0,33,85,80,144, +39,42,40,20,15,16,2,20,26,96,2,7,88,148,8,36,42,8,24,8,32, +9,223,0,33,92,88,148,8,36,41,50,55,9,223,0,33,93,88,148,8,36, +40,49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,163, +16,248,22,167,8,27,28,249,22,169,9,247,22,180,8,2,43,6,1,1,59, +6,1,1,58,250,22,137,8,6,14,14,40,91,94,126,97,93,42,41,126,97, +40,46,42,41,23,196,2,23,196,1,88,148,8,36,41,51,11,2,8,223,0, +33,98,80,144,39,44,40,20,15,16,2,88,148,39,40,8,38,8,128,6,2, +9,223,0,33,99,80,144,39,45,40,20,15,16,2,32,0,88,148,8,36,41, +50,11,2,12,222,33,100,80,144,39,48,40,20,15,16,2,32,0,88,148,8, +36,42,51,11,2,13,222,33,102,80,144,39,49,40,20,15,16,2,32,0,88, +148,8,36,41,49,11,2,14,222,33,103,80,144,39,50,40,20,15,16,2,88, +148,39,42,53,8,128,128,2,15,223,0,33,105,80,144,39,51,40,20,15,16, +2,88,148,39,44,55,8,128,128,2,17,223,0,33,107,80,144,39,53,40,20, +15,16,2,88,148,39,39,56,55,9,223,0,33,108,80,144,39,8,40,42,20, +15,16,2,88,148,39,39,47,16,4,39,40,8,128,4,39,2,18,223,0,33, +109,80,144,39,54,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,110, +80,144,39,8,41,42,20,15,16,2,88,148,39,39,47,16,4,39,40,8,128, +8,39,2,20,223,0,33,111,80,144,39,57,40,20,15,16,2,88,148,8,36, +39,8,38,8,128,6,9,223,0,33,112,80,144,39,8,42,42,20,15,16,2, +88,148,8,36,40,50,16,4,39,39,8,128,16,39,2,21,223,0,33,113,80, +144,39,58,40,20,15,16,2,20,28,143,32,0,88,148,39,40,48,11,2,22, +222,33,114,32,0,88,148,39,40,48,11,2,22,222,33,115,80,144,39,59,40, +20,15,16,2,88,148,8,36,40,50,8,240,0,128,0,0,2,23,223,0,33, +116,80,144,39,60,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,117, +80,144,39,8,43,42,20,15,16,2,88,148,8,36,40,51,16,4,39,40,8, +128,32,39,2,24,223,0,33,118,80,144,39,61,40,20,15,16,2,88,148,39, +40,56,55,2,19,223,0,33,119,80,144,39,56,40,20,15,16,2,88,148,8, +36,41,58,16,4,8,240,0,128,0,0,8,32,8,128,64,39,2,50,223,0, +33,120,80,144,39,8,44,42,20,15,16,2,88,148,8,36,42,52,16,4,39, +39,8,128,64,39,2,25,223,0,33,121,80,144,39,8,23,40,20,15,16,2, +88,148,39,39,56,55,9,223,0,33,122,80,144,39,8,45,42,20,15,16,2, +88,148,8,36,39,57,16,4,8,240,0,128,0,0,8,137,2,8,128,128,39, +2,26,223,0,33,123,80,144,39,8,24,40,20,15,16,2,247,22,140,2,80, +144,39,8,25,40,20,15,16,2,248,22,16,67,115,116,97,109,112,80,144,39, +8,26,40,20,15,16,2,88,148,39,40,49,8,240,0,0,0,4,9,223,0, +33,125,80,144,39,8,46,42,20,15,16,2,88,148,39,41,51,16,4,39,8, +128,80,8,240,0,64,0,0,39,2,29,223,0,33,133,2,80,144,39,8,27, +40,20,15,16,2,32,0,88,148,8,36,40,48,11,2,30,222,33,134,2,80, +144,39,8,29,40,20,15,16,2,88,148,8,36,42,48,8,240,0,0,0,2, +74,109,97,107,101,45,104,97,110,100,108,101,114,223,0,33,136,2,80,144,39, +8,47,42,20,15,16,2,88,148,39,40,47,16,4,8,128,6,8,128,104,8, +240,0,128,0,0,39,2,31,223,0,33,146,2,80,144,39,8,30,40,20,15, +16,2,88,148,39,41,59,16,2,39,8,240,0,128,0,0,2,32,223,0,33, +148,2,80,144,39,8,31,40,20,15,16,2,88,148,8,36,41,61,16,4,39, +8,240,0,64,0,0,39,40,2,50,223,0,33,149,2,80,144,39,8,48,42, +20,15,16,2,88,148,39,47,8,33,16,4,39,39,40,41,67,99,108,111,111, +112,223,0,33,156,2,80,144,39,8,49,42,20,15,16,2,88,148,39,44,8, +25,16,4,39,8,240,0,192,0,0,39,42,2,16,223,0,33,157,2,80,144, +39,52,40,20,15,16,2,88,148,39,42,58,16,4,47,39,43,39,2,33,223, +0,33,162,2,80,144,39,8,32,40,20,15,16,2,32,0,88,148,39,42,53, +11,2,35,222,33,163,2,80,144,39,8,34,40,20,15,16,2,32,0,88,148, +8,36,44,8,27,11,2,36,222,33,168,2,80,144,39,8,35,40,20,15,16, +2,20,28,143,32,0,88,148,8,36,41,55,11,2,37,222,33,171,2,88,148, +8,100,41,52,16,4,39,39,47,39,2,37,223,0,33,173,2,80,144,39,8, +36,40,20,15,16,2,20,28,143,32,0,88,148,8,36,41,55,11,2,34,222, +33,178,2,88,148,8,100,41,52,16,4,39,39,47,39,2,34,223,0,33,179, +2,80,144,39,8,33,40,20,15,16,2,20,28,143,32,0,88,148,39,40,47, +11,2,38,222,33,180,2,32,0,88,148,39,40,47,11,2,38,222,33,181,2, +80,144,39,8,37,40,20,15,16,2,88,148,8,36,40,58,16,4,55,41,39, +43,2,50,223,0,33,182,2,80,144,39,8,50,42,20,15,16,2,88,148,8, +36,40,58,16,4,55,41,39,47,2,50,223,0,33,183,2,80,144,39,8,51, +42,20,15,16,2,88,148,39,39,56,55,9,223,0,33,184,2,80,144,39,8, +52,42,20,15,16,2,88,148,8,36,40,8,23,16,4,55,41,39,8,32,2, +50,223,0,33,185,2,80,144,39,8,53,42,20,15,16,2,20,26,96,2,39, +88,148,39,39,60,16,4,8,32,8,140,2,39,43,9,223,0,33,186,2,88, +148,39,40,61,16,4,8,32,8,140,2,39,47,9,223,0,33,187,2,88,148, +39,41,8,30,16,4,8,48,8,139,2,39,8,48,9,223,0,33,188,2,80, +144,39,8,38,40,20,15,16,2,88,148,8,36,40,60,16,4,8,128,6,39, +39,8,64,2,50,223,0,33,189,2,80,144,39,8,54,42,20,15,16,2,88, +148,8,36,42,56,16,4,55,39,39,8,64,2,40,223,0,33,191,2,80,144, +39,8,39,40,95,29,94,2,10,70,35,37,107,101,114,110,101,108,11,29,94, +2,10,71,35,37,109,105,110,45,115,116,120,11,2,11,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 19760); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,8,0, -23,0,48,0,65,0,83,0,105,0,128,0,149,0,171,0,180,0,189,0,196, -0,205,0,212,0,0,0,247,1,0,0,3,1,5,105,110,115,112,48,76,35, -37,112,108,97,99,101,45,115,116,114,117,99,116,1,23,115,116,114,117,99,116, -58,84,72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,78,84,72,45, -112,108,97,99,101,45,99,104,97,110,110,101,108,79,84,72,45,112,108,97,99, -101,45,99,104,97,110,110,101,108,63,1,20,84,72,45,112,108,97,99,101,45, -99,104,97,110,110,101,108,45,114,101,102,1,21,84,72,45,112,108,97,99,101, -45,99,104,97,110,110,101,108,45,115,101,116,33,1,19,84,72,45,112,108,97, -99,101,45,99,104,97,110,110,101,108,45,105,110,1,20,84,72,45,112,108,97, -99,101,45,99,104,97,110,110,101,108,45,111,117,116,249,80,143,41,42,23,196, -1,39,249,80,143,41,42,23,196,1,39,249,80,143,41,42,195,39,249,80,143, -41,42,23,196,1,40,249,80,143,41,42,195,40,144,39,20,121,145,2,1,39, -16,1,11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11, -11,9,9,11,11,11,10,48,80,143,39,39,20,121,145,2,1,39,16,7,2, -3,2,4,2,5,2,6,2,7,2,8,2,9,16,0,40,42,39,16,0,39, -16,2,2,6,2,7,41,11,11,11,16,5,2,4,2,8,2,9,2,5,2, -3,16,5,11,11,11,11,11,16,5,2,4,2,8,2,9,2,5,2,3,44, -44,40,12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0, -16,0,39,39,16,3,20,15,16,6,253,22,189,10,2,4,11,41,39,11,248, -22,90,249,22,80,22,175,10,88,148,39,40,48,47,9,223,9,33,10,80,144, -39,39,40,80,144,39,40,40,80,144,39,41,40,80,144,39,42,40,80,144,39, -43,40,20,15,16,2,20,28,143,88,148,39,40,48,47,9,223,0,33,11,88, -148,39,40,48,47,9,223,0,33,12,80,144,39,44,40,20,15,16,2,20,28, -143,88,148,39,40,48,47,9,223,0,33,13,88,148,39,40,48,47,9,223,0, -33,14,80,144,39,45,40,93,29,94,67,113,117,111,116,101,70,35,37,107,101, -114,110,101,108,11,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 577); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,8, +0,23,0,48,0,65,0,83,0,105,0,128,0,149,0,171,0,180,0,189,0, +196,0,205,0,212,0,0,0,247,1,0,0,3,1,5,105,110,115,112,48,76, +35,37,112,108,97,99,101,45,115,116,114,117,99,116,1,23,115,116,114,117,99, +116,58,84,72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,78,84,72, +45,112,108,97,99,101,45,99,104,97,110,110,101,108,79,84,72,45,112,108,97, +99,101,45,99,104,97,110,110,101,108,63,1,20,84,72,45,112,108,97,99,101, +45,99,104,97,110,110,101,108,45,114,101,102,1,21,84,72,45,112,108,97,99, +101,45,99,104,97,110,110,101,108,45,115,101,116,33,1,19,84,72,45,112,108, +97,99,101,45,99,104,97,110,110,101,108,45,105,110,1,20,84,72,45,112,108, +97,99,101,45,99,104,97,110,110,101,108,45,111,117,116,249,80,143,41,42,23, +196,1,39,249,80,143,41,42,23,196,1,39,249,80,143,41,42,195,39,249,80, +143,41,42,23,196,1,40,249,80,143,41,42,195,40,144,39,20,121,145,2,1, +39,16,1,11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11, +11,11,9,9,11,11,11,10,48,80,143,39,39,20,121,145,2,1,39,16,7, +2,3,2,4,2,5,2,6,2,7,2,8,2,9,16,0,40,42,39,16,0, +39,16,2,2,6,2,7,41,11,11,11,16,5,2,4,2,8,2,9,2,5, +2,3,16,5,11,11,11,11,11,16,5,2,4,2,8,2,9,2,5,2,3, +44,44,40,12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16, +0,16,0,39,39,16,3,20,15,16,6,253,22,189,10,2,4,11,41,39,11, +248,22,90,249,22,80,22,175,10,88,148,39,40,48,47,9,223,9,33,10,80, +144,39,39,40,80,144,39,40,40,80,144,39,41,40,80,144,39,42,40,80,144, +39,43,40,20,15,16,2,20,28,143,88,148,39,40,48,47,9,223,0,33,11, +88,148,39,40,48,47,9,223,0,33,12,80,144,39,44,40,20,15,16,2,20, +28,143,88,148,39,40,48,47,9,223,0,33,13,88,148,39,40,48,47,9,223, +0,33,14,80,144,39,45,40,93,29,94,67,113,117,111,116,101,70,35,37,107, +101,114,110,101,108,11,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 578); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,1,0,0,8,0, -15,0,26,0,53,0,59,0,73,0,86,0,112,0,129,0,151,0,159,0,171, -0,186,0,202,0,220,0,241,0,253,0,13,1,36,1,60,1,72,1,103,1, -108,1,113,1,131,1,137,1,142,1,151,1,156,1,162,1,167,1,171,1,186, -1,193,1,198,1,202,1,207,1,214,1,225,1,232,1,240,1,87,2,122,2, -225,2,4,3,98,3,133,3,227,3,6,4,7,11,37,11,88,11,163,11,179, -11,195,11,209,11,225,11,44,12,60,12,76,12,92,12,167,12,74,13,90,13, -165,13,160,14,40,15,115,15,22,16,35,16,188,16,116,17,159,17,241,17,113, -18,174,18,182,18,193,18,227,19,74,20,102,20,115,20,36,21,43,21,203,21, -223,21,67,22,89,22,99,22,113,22,151,22,250,22,254,22,5,23,211,23,104, -32,157,32,181,32,205,32,0,0,253,36,0,0,3,1,5,105,110,115,112,48, -68,35,37,98,111,111,116,72,100,108,108,45,115,117,102,102,105,120,1,25,100, -101,102,97,117,108,116,45,108,111,97,100,47,117,115,101,45,99,111,109,112,105, -108,101,100,67,113,117,111,116,101,29,94,2,5,70,35,37,112,97,114,97,109, -122,11,29,94,2,5,69,35,37,117,116,105,108,115,11,1,24,45,109,111,100, -117,108,101,45,104,97,115,104,45,116,97,98,108,101,45,116,97,98,108,101,78, -114,101,103,105,115,116,101,114,45,122,111,45,112,97,116,104,1,20,100,101,102, -97,117,108,116,45,114,101,97,100,101,114,45,103,117,97,114,100,69,67,65,67, -72,69,45,78,73,45,112,97,116,104,45,99,97,99,104,101,76,112,97,116,104, -45,99,97,99,104,101,45,103,101,116,77,112,97,116,104,45,99,97,99,104,101, -45,115,101,116,33,79,45,108,111,97,100,105,110,103,45,102,105,108,101,110,97, -109,101,1,19,45,108,111,97,100,105,110,103,45,112,114,111,109,112,116,45,116, -97,103,73,45,112,114,101,118,45,114,101,108,116,111,77,45,112,114,101,118,45, -114,101,108,116,111,45,100,105,114,1,21,115,112,108,105,116,45,114,101,108,97, -116,105,118,101,45,115,116,114,105,110,103,1,22,102,111,114,109,97,116,45,115, -111,117,114,99,101,45,108,111,99,97,116,105,111,110,73,111,114,105,103,45,112, -97,114,97,109,122,1,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108, -101,45,110,97,109,101,45,114,101,115,111,108,118,101,114,66,98,111,111,116,66, -115,101,97,108,79,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101, -100,5,4,46,114,107,116,66,115,97,109,101,6,6,6,110,97,116,105,118,101, -5,3,46,122,111,67,105,108,111,111,112,66,108,111,111,112,65,108,105,98,6, -12,12,109,111,100,117,108,101,45,112,97,116,104,63,68,115,117,98,109,111,100, -6,2,2,46,46,6,1,1,46,66,102,105,108,101,68,112,108,97,110,101,116, -6,8,8,109,97,105,110,46,114,107,116,6,4,4,46,114,107,116,69,105,103, -110,111,114,101,100,27,252,22,128,16,28,249,22,169,9,23,201,2,2,27,86, -94,23,199,1,23,200,1,28,248,22,133,16,23,200,2,249,22,128,16,23,202, -1,23,201,1,249,80,144,50,45,42,23,202,1,23,201,1,23,203,1,2,28, -247,22,181,8,249,80,144,50,46,42,23,203,1,80,144,50,39,41,27,250,22, -146,16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80, -195,194,11,249,22,5,20,20,96,88,148,8,36,40,57,8,129,3,9,226,5, -4,3,6,33,42,23,199,1,23,196,1,23,197,1,23,195,1,27,252,22,128, -16,28,249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28,248, -22,133,16,23,200,2,249,22,128,16,23,202,1,23,201,1,249,80,144,50,45, -42,23,202,1,23,201,1,23,203,1,2,28,247,22,181,8,249,80,144,50,46, -42,23,203,1,80,144,50,39,41,27,250,22,146,16,196,11,32,0,88,148,8, -36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5,20,20,96, -88,148,8,36,40,57,8,129,3,9,226,5,4,3,6,33,44,23,199,1,23, -196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169,9,23,199,2, -2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198,2,249,22,128, -16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23,201, -1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16,196,11,32,0, -88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5, -20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6,33,46,23, -199,1,23,196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169,9, -23,199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198,2, -249,22,128,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199, -1,23,201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16,196, -11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11, -249,22,5,20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6, -33,48,23,199,1,23,196,1,23,197,1,23,195,1,86,95,28,248,80,144,40, -43,42,23,195,2,12,250,22,181,11,2,25,6,12,12,112,97,116,104,45,115, -116,114,105,110,103,63,23,197,2,28,28,23,195,2,28,248,22,64,23,196,2, -10,28,248,22,89,23,196,2,28,249,22,130,4,248,22,93,23,198,2,40,28, -28,248,22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,162,20,23,197, -2,249,22,4,22,64,248,22,163,20,23,198,2,11,11,11,10,12,250,22,181, -11,2,25,6,71,71,40,111,114,47,99,32,35,102,32,115,121,109,98,111,108, -63,32,40,99,111,110,115,47,99,32,40,111,114,47,99,32,35,102,32,115,121, -109,98,111,108,63,41,32,40,110,111,110,45,101,109,112,116,121,45,108,105,115, -116,111,102,32,115,121,109,98,111,108,63,41,41,41,23,197,2,27,28,23,196, -2,247,22,191,4,11,27,28,23,194,2,250,22,158,2,80,143,44,44,248,22, -128,17,247,22,144,14,11,11,27,28,23,194,2,250,22,158,2,248,22,82,23, -198,2,23,198,2,11,11,28,23,193,2,86,96,23,197,1,23,195,1,23,194, -1,20,13,144,80,144,42,41,40,250,80,144,45,42,40,249,22,31,11,80,144, -47,41,40,22,128,5,248,22,102,23,197,2,27,248,22,111,23,195,2,20,13, -144,80,144,43,41,40,250,80,144,46,42,40,249,22,31,11,80,144,48,41,40, -22,177,5,28,248,22,174,15,23,197,2,23,196,1,86,94,23,196,1,247,22, -152,16,249,247,22,175,5,248,22,162,20,23,197,1,23,201,1,86,94,23,193, -1,27,28,248,22,135,16,23,199,2,23,198,2,27,247,22,177,5,28,192,249, -22,136,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248,22, -131,16,23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28,23, -204,2,27,248,22,179,15,23,198,2,19,248,22,147,8,194,28,28,249,22,132, -4,23,195,4,43,249,22,150,8,2,26,249,22,153,8,197,249,22,184,3,23, -199,4,43,11,249,22,7,23,200,2,248,22,183,15,249,22,154,8,250,22,153, -8,201,39,249,22,184,3,23,203,4,43,5,3,46,115,115,249,22,7,23,200, -2,11,2,249,22,7,23,198,2,11,27,28,249,22,169,9,23,196,2,23,199, -2,23,199,2,249,22,128,16,23,198,2,23,196,2,27,28,23,196,2,28,249, -22,169,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,128,16, -23,199,2,23,198,2,86,94,23,198,1,11,27,28,249,22,169,9,23,200,2, -70,114,101,108,97,116,105,118,101,86,94,23,198,1,2,27,23,198,1,27,247, -22,157,16,27,247,22,158,16,27,250,22,146,16,23,201,2,11,32,0,88,148, -8,36,39,44,11,9,222,11,27,28,23,194,2,249,22,80,23,201,2,23,196, -1,86,94,23,194,1,11,27,28,23,199,2,28,23,194,2,11,27,250,22,146, -16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22, -80,23,202,2,194,11,11,27,28,23,195,2,23,195,2,23,194,2,27,28,23, -196,2,23,196,2,248,22,167,9,23,196,2,27,28,23,205,2,28,23,196,2, -86,94,23,197,1,23,196,2,248,22,167,9,23,198,1,11,27,28,23,195,2, -27,249,22,5,88,148,39,40,51,8,129,3,9,226,24,15,12,11,33,43,23, -203,2,27,28,23,198,2,11,193,28,192,192,28,193,28,23,198,2,28,249,22, -132,4,248,22,82,196,248,22,82,23,201,2,193,11,11,11,11,28,23,193,2, -86,105,23,213,1,23,212,1,23,206,1,23,205,1,23,204,1,23,203,1,23, -201,1,23,200,1,23,197,1,23,196,1,23,195,1,23,194,1,20,13,144,80, -144,60,41,40,250,80,144,8,24,42,40,249,22,31,11,80,144,8,26,41,40, -22,128,5,11,20,13,144,80,144,60,41,40,250,80,144,8,24,42,40,249,22, -31,11,80,144,8,26,41,40,22,177,5,28,248,22,174,15,23,206,2,23,205, -1,86,94,23,205,1,247,22,152,16,249,247,22,162,16,248,22,81,23,196,1, -23,218,1,86,94,23,193,1,27,28,23,195,2,27,249,22,5,88,148,39,40, -51,8,129,3,9,226,25,17,13,12,33,45,23,204,2,27,28,23,200,2,11, -193,28,192,192,28,193,28,199,28,249,22,132,4,248,22,82,196,248,22,82,202, -193,11,11,11,11,28,23,193,2,86,103,23,214,1,23,213,1,23,207,1,23, -206,1,23,205,1,23,202,1,23,201,1,23,197,1,23,196,1,23,195,1,20, -13,144,80,144,61,41,40,250,80,144,8,25,42,40,249,22,31,11,80,144,8, -27,41,40,22,128,5,23,207,1,20,13,144,80,144,61,41,40,250,80,144,8, -25,42,40,249,22,31,11,80,144,8,27,41,40,22,177,5,28,248,22,174,15, -23,207,2,23,206,1,86,94,23,206,1,247,22,152,16,249,247,22,162,16,248, -22,81,23,196,1,23,219,1,86,94,23,193,1,27,28,23,197,2,27,249,22, -5,20,20,94,88,148,39,40,51,8,128,3,9,226,26,17,14,13,33,47,23, -210,1,23,205,2,27,28,23,200,2,11,193,28,192,192,28,193,28,23,200,2, -28,249,22,132,4,248,22,82,196,248,22,82,23,203,2,193,11,11,11,86,94, -23,207,1,11,28,23,193,2,86,101,23,208,1,23,206,1,23,205,1,23,203, -1,23,202,1,23,198,1,23,197,1,23,196,1,86,94,27,248,22,81,23,195, -2,28,23,215,2,250,22,156,2,248,22,82,23,219,1,23,219,1,250,22,90, -23,199,1,11,23,211,2,12,20,13,144,80,144,8,23,41,40,250,80,144,8, -26,42,40,249,22,31,11,80,144,8,28,41,40,22,128,5,11,20,13,144,80, -144,8,23,41,40,250,80,144,8,26,42,40,249,22,31,11,80,144,8,28,41, -40,22,177,5,28,248,22,174,15,23,208,2,23,207,1,86,94,23,207,1,247, -22,152,16,249,247,22,175,5,248,22,162,20,23,196,1,23,220,1,86,94,23, -193,1,27,28,23,197,1,27,249,22,5,20,20,95,88,148,39,40,51,8,128, -3,9,226,27,19,15,14,33,49,23,207,1,23,212,1,23,206,1,27,28,23, -201,2,11,193,28,192,192,28,193,28,200,28,249,22,132,4,248,22,82,196,248, -22,82,203,193,11,11,11,86,96,23,209,1,23,204,1,23,203,1,11,28,23, -193,2,86,95,23,207,1,23,198,1,86,94,27,248,22,81,23,195,2,28,23, -216,2,250,22,156,2,248,22,82,23,220,1,23,220,1,250,22,90,23,199,1, -23,213,2,23,212,2,12,20,13,144,80,144,8,24,41,40,250,80,144,8,27, -42,40,249,22,31,11,80,144,8,29,41,40,22,128,5,23,209,1,20,13,144, -80,144,8,24,41,40,250,80,144,8,27,42,40,249,22,31,11,80,144,8,29, -41,40,22,177,5,28,248,22,174,15,23,209,2,23,208,1,86,94,23,208,1, -247,22,152,16,249,247,22,175,5,248,22,162,20,23,196,1,23,221,1,86,94, -23,193,1,28,28,248,22,78,23,220,2,248,22,162,20,23,220,2,10,27,28, -23,199,2,86,94,23,207,1,23,208,1,86,94,23,208,1,23,207,1,28,28, -248,22,78,23,221,2,248,22,167,9,248,22,186,15,23,195,2,11,12,20,13, -144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22,31,11,80,144,8, -30,41,40,22,128,5,28,23,223,2,28,23,202,1,11,23,196,2,86,94,23, -202,1,11,20,13,144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22, -31,11,80,144,8,30,41,40,22,177,5,28,248,22,174,15,23,210,2,23,209, -1,86,94,23,209,1,247,22,152,16,249,247,22,175,5,23,195,1,23,222,1, -12,28,23,194,2,250,22,156,2,248,22,82,23,198,1,23,196,1,250,22,90, -23,201,1,23,202,1,23,203,1,12,27,249,22,189,8,80,144,42,50,41,249, -22,191,3,248,22,187,3,248,22,173,2,200,8,128,8,27,28,193,248,22,176, -2,194,11,28,192,27,249,22,100,198,195,28,192,248,22,82,193,11,11,27,249, -22,191,3,248,22,187,3,248,22,173,2,23,199,2,8,128,8,27,249,22,189, -8,80,144,43,50,41,23,196,2,250,22,190,8,80,144,44,50,41,23,197,1, -248,22,175,2,249,22,80,249,22,80,23,204,1,23,205,1,27,28,23,200,2, -248,22,176,2,200,11,28,192,192,9,32,54,88,149,8,38,42,54,11,2,30, -39,223,3,33,69,32,55,88,149,8,38,42,53,11,2,30,39,223,3,33,68, -32,56,88,148,8,36,40,53,11,2,31,222,33,67,32,57,88,149,8,38,42, -53,11,2,30,39,223,3,33,58,28,249,22,128,4,23,197,2,23,195,4,248, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,1,0,0,8, +0,15,0,26,0,53,0,59,0,73,0,86,0,112,0,129,0,151,0,159,0, +171,0,186,0,202,0,220,0,241,0,253,0,13,1,36,1,60,1,72,1,103, +1,108,1,113,1,131,1,137,1,142,1,151,1,156,1,162,1,167,1,171,1, +186,1,193,1,198,1,202,1,207,1,214,1,225,1,232,1,240,1,87,2,122, +2,225,2,4,3,98,3,133,3,227,3,6,4,7,11,37,11,88,11,163,11, +179,11,195,11,209,11,225,11,44,12,60,12,76,12,92,12,167,12,74,13,90, +13,165,13,160,14,40,15,115,15,22,16,35,16,188,16,116,17,159,17,241,17, +113,18,174,18,182,18,193,18,227,19,74,20,102,20,115,20,36,21,43,21,203, +21,223,21,67,22,89,22,99,22,113,22,151,22,250,22,254,22,5,23,211,23, +104,32,157,32,181,32,205,32,0,0,253,36,0,0,3,1,5,105,110,115,112, +48,68,35,37,98,111,111,116,72,100,108,108,45,115,117,102,102,105,120,1,25, +100,101,102,97,117,108,116,45,108,111,97,100,47,117,115,101,45,99,111,109,112, +105,108,101,100,67,113,117,111,116,101,29,94,2,5,70,35,37,112,97,114,97, +109,122,11,29,94,2,5,69,35,37,117,116,105,108,115,11,1,24,45,109,111, +100,117,108,101,45,104,97,115,104,45,116,97,98,108,101,45,116,97,98,108,101, +78,114,101,103,105,115,116,101,114,45,122,111,45,112,97,116,104,1,20,100,101, +102,97,117,108,116,45,114,101,97,100,101,114,45,103,117,97,114,100,69,67,65, +67,72,69,45,78,73,45,112,97,116,104,45,99,97,99,104,101,76,112,97,116, +104,45,99,97,99,104,101,45,103,101,116,77,112,97,116,104,45,99,97,99,104, +101,45,115,101,116,33,79,45,108,111,97,100,105,110,103,45,102,105,108,101,110, +97,109,101,1,19,45,108,111,97,100,105,110,103,45,112,114,111,109,112,116,45, +116,97,103,73,45,112,114,101,118,45,114,101,108,116,111,77,45,112,114,101,118, +45,114,101,108,116,111,45,100,105,114,1,21,115,112,108,105,116,45,114,101,108, +97,116,105,118,101,45,115,116,114,105,110,103,1,22,102,111,114,109,97,116,45, +115,111,117,114,99,101,45,108,111,99,97,116,105,111,110,73,111,114,105,103,45, +112,97,114,97,109,122,1,29,115,116,97,110,100,97,114,100,45,109,111,100,117, +108,101,45,110,97,109,101,45,114,101,115,111,108,118,101,114,66,98,111,111,116, +66,115,101,97,108,79,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108, +101,100,5,4,46,114,107,116,66,115,97,109,101,6,6,6,110,97,116,105,118, +101,5,3,46,122,111,67,105,108,111,111,112,66,108,111,111,112,65,108,105,98, +6,12,12,109,111,100,117,108,101,45,112,97,116,104,63,68,115,117,98,109,111, +100,6,2,2,46,46,6,1,1,46,66,102,105,108,101,68,112,108,97,110,101, +116,6,8,8,109,97,105,110,46,114,107,116,6,4,4,46,114,107,116,69,105, +103,110,111,114,101,100,27,252,22,128,16,28,249,22,169,9,23,201,2,2,27, +86,94,23,199,1,23,200,1,28,248,22,133,16,23,200,2,249,22,128,16,23, +202,1,23,201,1,249,80,144,50,45,42,23,202,1,23,201,1,23,203,1,2, +28,247,22,181,8,249,80,144,50,46,42,23,203,1,80,144,50,39,41,27,250, +22,146,16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22, +80,195,194,11,249,22,5,20,20,96,88,148,8,36,40,57,8,129,3,9,226, +5,4,3,6,33,42,23,199,1,23,196,1,23,197,1,23,195,1,27,252,22, +128,16,28,249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28, +248,22,133,16,23,200,2,249,22,128,16,23,202,1,23,201,1,249,80,144,50, +45,42,23,202,1,23,201,1,23,203,1,2,28,247,22,181,8,249,80,144,50, +46,42,23,203,1,80,144,50,39,41,27,250,22,146,16,196,11,32,0,88,148, +8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5,20,20, +96,88,148,8,36,40,57,8,129,3,9,226,5,4,3,6,33,44,23,199,1, +23,196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169,9,23,199, +2,2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198,2,249,22, +128,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23, +201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16,196,11,32, +0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22, +5,20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6,33,46, +23,199,1,23,196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169, +9,23,199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198, +2,249,22,128,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23, +199,1,23,201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16, +196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194, +11,249,22,5,20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3, +6,33,48,23,199,1,23,196,1,23,197,1,23,195,1,86,95,28,248,80,144, +40,43,42,23,195,2,12,250,22,181,11,2,25,6,12,12,112,97,116,104,45, +115,116,114,105,110,103,63,23,197,2,28,28,23,195,2,28,248,22,64,23,196, +2,10,28,248,22,89,23,196,2,28,249,22,130,4,248,22,93,23,198,2,40, +28,28,248,22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,163,20,23, +197,2,249,22,4,22,64,248,22,164,20,23,198,2,11,11,11,10,12,250,22, +181,11,2,25,6,71,71,40,111,114,47,99,32,35,102,32,115,121,109,98,111, +108,63,32,40,99,111,110,115,47,99,32,40,111,114,47,99,32,35,102,32,115, +121,109,98,111,108,63,41,32,40,110,111,110,45,101,109,112,116,121,45,108,105, +115,116,111,102,32,115,121,109,98,111,108,63,41,41,41,23,197,2,27,28,23, +196,2,247,22,191,4,11,27,28,23,194,2,250,22,158,2,80,143,44,44,248, +22,128,17,247,22,144,14,11,11,27,28,23,194,2,250,22,158,2,248,22,82, +23,198,2,23,198,2,11,11,28,23,193,2,86,96,23,197,1,23,195,1,23, +194,1,20,13,144,80,144,42,41,40,250,80,144,45,42,40,249,22,31,11,80, +144,47,41,40,22,128,5,248,22,102,23,197,2,27,248,22,111,23,195,2,20, +13,144,80,144,43,41,40,250,80,144,46,42,40,249,22,31,11,80,144,48,41, +40,22,177,5,28,248,22,174,15,23,197,2,23,196,1,86,94,23,196,1,247, +22,152,16,249,247,22,175,5,248,22,163,20,23,197,1,23,201,1,86,94,23, +193,1,27,28,248,22,135,16,23,199,2,23,198,2,27,247,22,177,5,28,192, +249,22,136,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248, +22,131,16,23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28, +23,204,2,27,248,22,179,15,23,198,2,19,248,22,147,8,194,28,28,249,22, +132,4,23,195,4,43,249,22,150,8,2,26,249,22,153,8,197,249,22,184,3, +23,199,4,43,11,249,22,7,23,200,2,248,22,183,15,249,22,154,8,250,22, +153,8,201,39,249,22,184,3,23,203,4,43,5,3,46,115,115,249,22,7,23, +200,2,11,2,249,22,7,23,198,2,11,27,28,249,22,169,9,23,196,2,23, +199,2,23,199,2,249,22,128,16,23,198,2,23,196,2,27,28,23,196,2,28, +249,22,169,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,128, +16,23,199,2,23,198,2,86,94,23,198,1,11,27,28,249,22,169,9,23,200, +2,70,114,101,108,97,116,105,118,101,86,94,23,198,1,2,27,23,198,1,27, +247,22,157,16,27,247,22,158,16,27,250,22,146,16,23,201,2,11,32,0,88, +148,8,36,39,44,11,9,222,11,27,28,23,194,2,249,22,80,23,201,2,23, +196,1,86,94,23,194,1,11,27,28,23,199,2,28,23,194,2,11,27,250,22, +146,16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249, +22,80,23,202,2,194,11,11,27,28,23,195,2,23,195,2,23,194,2,27,28, +23,196,2,23,196,2,248,22,167,9,23,196,2,27,28,23,205,2,28,23,196, +2,86,94,23,197,1,23,196,2,248,22,167,9,23,198,1,11,27,28,23,195, +2,27,249,22,5,88,148,39,40,51,8,129,3,9,226,24,15,12,11,33,43, +23,203,2,27,28,23,198,2,11,193,28,192,192,28,193,28,23,198,2,28,249, +22,132,4,248,22,82,196,248,22,82,23,201,2,193,11,11,11,11,28,23,193, +2,86,105,23,213,1,23,212,1,23,206,1,23,205,1,23,204,1,23,203,1, +23,201,1,23,200,1,23,197,1,23,196,1,23,195,1,23,194,1,20,13,144, +80,144,60,41,40,250,80,144,8,24,42,40,249,22,31,11,80,144,8,26,41, +40,22,128,5,11,20,13,144,80,144,60,41,40,250,80,144,8,24,42,40,249, +22,31,11,80,144,8,26,41,40,22,177,5,28,248,22,174,15,23,206,2,23, +205,1,86,94,23,205,1,247,22,152,16,249,247,22,162,16,248,22,81,23,196, +1,23,218,1,86,94,23,193,1,27,28,23,195,2,27,249,22,5,88,148,39, +40,51,8,129,3,9,226,25,17,13,12,33,45,23,204,2,27,28,23,200,2, +11,193,28,192,192,28,193,28,199,28,249,22,132,4,248,22,82,196,248,22,82, +202,193,11,11,11,11,28,23,193,2,86,103,23,214,1,23,213,1,23,207,1, +23,206,1,23,205,1,23,202,1,23,201,1,23,197,1,23,196,1,23,195,1, +20,13,144,80,144,61,41,40,250,80,144,8,25,42,40,249,22,31,11,80,144, +8,27,41,40,22,128,5,23,207,1,20,13,144,80,144,61,41,40,250,80,144, +8,25,42,40,249,22,31,11,80,144,8,27,41,40,22,177,5,28,248,22,174, +15,23,207,2,23,206,1,86,94,23,206,1,247,22,152,16,249,247,22,162,16, +248,22,81,23,196,1,23,219,1,86,94,23,193,1,27,28,23,197,2,27,249, +22,5,20,20,94,88,148,39,40,51,8,128,3,9,226,26,17,14,13,33,47, +23,210,1,23,205,2,27,28,23,200,2,11,193,28,192,192,28,193,28,23,200, +2,28,249,22,132,4,248,22,82,196,248,22,82,23,203,2,193,11,11,11,86, +94,23,207,1,11,28,23,193,2,86,101,23,208,1,23,206,1,23,205,1,23, +203,1,23,202,1,23,198,1,23,197,1,23,196,1,86,94,27,248,22,81,23, +195,2,28,23,215,2,250,22,156,2,248,22,82,23,219,1,23,219,1,250,22, +90,23,199,1,11,23,211,2,12,20,13,144,80,144,8,23,41,40,250,80,144, +8,26,42,40,249,22,31,11,80,144,8,28,41,40,22,128,5,11,20,13,144, +80,144,8,23,41,40,250,80,144,8,26,42,40,249,22,31,11,80,144,8,28, +41,40,22,177,5,28,248,22,174,15,23,208,2,23,207,1,86,94,23,207,1, +247,22,152,16,249,247,22,175,5,248,22,163,20,23,196,1,23,220,1,86,94, +23,193,1,27,28,23,197,1,27,249,22,5,20,20,95,88,148,39,40,51,8, +128,3,9,226,27,19,15,14,33,49,23,207,1,23,212,1,23,206,1,27,28, +23,201,2,11,193,28,192,192,28,193,28,200,28,249,22,132,4,248,22,82,196, +248,22,82,203,193,11,11,11,86,96,23,209,1,23,204,1,23,203,1,11,28, +23,193,2,86,95,23,207,1,23,198,1,86,94,27,248,22,81,23,195,2,28, +23,216,2,250,22,156,2,248,22,82,23,220,1,23,220,1,250,22,90,23,199, +1,23,213,2,23,212,2,12,20,13,144,80,144,8,24,41,40,250,80,144,8, +27,42,40,249,22,31,11,80,144,8,29,41,40,22,128,5,23,209,1,20,13, +144,80,144,8,24,41,40,250,80,144,8,27,42,40,249,22,31,11,80,144,8, +29,41,40,22,177,5,28,248,22,174,15,23,209,2,23,208,1,86,94,23,208, +1,247,22,152,16,249,247,22,175,5,248,22,163,20,23,196,1,23,221,1,86, +94,23,193,1,28,28,248,22,78,23,220,2,248,22,163,20,23,220,2,10,27, +28,23,199,2,86,94,23,207,1,23,208,1,86,94,23,208,1,23,207,1,28, +28,248,22,78,23,221,2,248,22,167,9,248,22,186,15,23,195,2,11,12,20, +13,144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22,31,11,80,144, +8,30,41,40,22,128,5,28,23,223,2,28,23,202,1,11,23,196,2,86,94, +23,202,1,11,20,13,144,80,144,8,25,41,40,250,80,144,8,28,42,40,249, +22,31,11,80,144,8,30,41,40,22,177,5,28,248,22,174,15,23,210,2,23, +209,1,86,94,23,209,1,247,22,152,16,249,247,22,175,5,23,195,1,23,222, +1,12,28,23,194,2,250,22,156,2,248,22,82,23,198,1,23,196,1,250,22, +90,23,201,1,23,202,1,23,203,1,12,27,249,22,189,8,80,144,42,50,41, +249,22,191,3,248,22,187,3,248,22,173,2,200,8,128,8,27,28,193,248,22, +176,2,194,11,28,192,27,249,22,100,198,195,28,192,248,22,82,193,11,11,27, +249,22,191,3,248,22,187,3,248,22,173,2,23,199,2,8,128,8,27,249,22, +189,8,80,144,43,50,41,23,196,2,250,22,190,8,80,144,44,50,41,23,197, +1,248,22,175,2,249,22,80,249,22,80,23,204,1,23,205,1,27,28,23,200, +2,248,22,176,2,200,11,28,192,192,9,32,54,88,149,8,38,42,54,11,2, +30,39,223,3,33,69,32,55,88,149,8,38,42,53,11,2,30,39,223,3,33, +68,32,56,88,148,8,36,40,53,11,2,31,222,33,67,32,57,88,149,8,38, +42,53,11,2,30,39,223,3,33,58,28,249,22,128,4,23,197,2,23,195,4, +248,22,90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2, +249,22,80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7, +23,199,1,248,22,181,3,23,201,1,250,2,57,23,196,4,196,248,22,181,3, +198,32,59,88,149,8,38,42,55,11,2,30,39,223,3,33,66,32,60,88,149, +8,38,42,54,11,2,30,39,223,3,33,63,32,61,88,149,8,38,42,53,11, +2,30,39,223,3,33,62,28,249,22,128,4,23,197,2,23,195,4,248,22,90, +194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249,22,80, +250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23,199,1, +248,22,181,3,23,201,1,250,2,61,23,196,4,196,248,22,181,3,198,28,249, +22,128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7,47,249, +22,157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2,39,23, +200,2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248,22,156, +7,23,195,2,250,2,61,23,196,4,23,197,1,39,2,27,248,22,181,3,23, +197,1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249,22,136, +9,7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175,7,23, +200,2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181,3,23, +199,1,250,2,60,23,197,4,197,248,22,181,3,196,32,64,88,149,8,38,42, +53,11,2,30,39,223,3,33,65,28,249,22,128,4,23,197,2,23,195,4,248, 22,90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249, 22,80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23, -199,1,248,22,181,3,23,201,1,250,2,57,23,196,4,196,248,22,181,3,198, -32,59,88,149,8,38,42,55,11,2,30,39,223,3,33,66,32,60,88,149,8, -38,42,54,11,2,30,39,223,3,33,63,32,61,88,149,8,38,42,53,11,2, -30,39,223,3,33,62,28,249,22,128,4,23,197,2,23,195,4,248,22,90,194, -28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249,22,80,250, -22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23,199,1,248, -22,181,3,23,201,1,250,2,61,23,196,4,196,248,22,181,3,198,28,249,22, -128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7,47,249,22, -157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2,39,23,200, -2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248,22,156,7, -23,195,2,250,2,61,23,196,4,23,197,1,39,2,27,248,22,181,3,23,197, -1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249,22,136,9, -7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175,7,23,200, -2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181,3,23,199, -1,250,2,60,23,197,4,197,248,22,181,3,196,32,64,88,149,8,38,42,53, -11,2,30,39,223,3,33,65,28,249,22,128,4,23,197,2,23,195,4,248,22, -90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249,22, -80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23,199, -1,248,22,181,3,23,201,1,250,2,64,23,196,4,196,248,22,181,3,198,28, -249,22,128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7,47, -249,22,157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2,39, -23,200,2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248,22, -156,7,23,195,2,250,2,60,23,196,4,23,197,1,39,2,27,248,22,181,3, -23,197,1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249,22, -136,9,7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175,7, -23,200,2,39,23,198,2,27,249,22,175,7,23,200,1,248,22,181,3,23,199, -1,19,248,22,156,7,23,195,2,250,2,64,23,196,4,23,197,1,39,2,27, -248,22,181,3,23,195,1,28,249,22,128,4,23,195,2,23,197,4,248,22,90, -196,28,249,22,136,9,7,47,249,22,157,7,23,200,2,23,197,2,249,22,80, -250,22,175,7,23,201,2,39,23,198,2,248,2,56,249,22,175,7,23,201,1, -248,22,181,3,23,199,1,250,2,59,23,198,4,198,248,22,181,3,196,19,248, -22,156,7,23,195,2,28,249,22,128,4,39,23,195,4,248,22,90,194,28,249, -22,136,9,7,47,249,22,157,7,23,198,2,39,249,22,80,250,22,175,7,23, -199,2,39,39,27,249,22,175,7,23,199,1,40,19,248,22,156,7,23,195,2, -250,2,57,23,196,4,23,197,1,39,2,28,249,22,128,4,40,23,195,4,248, -22,90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,40,249,22,80, -250,22,175,7,23,199,2,39,40,248,2,56,249,22,175,7,23,199,1,41,250, -2,59,23,196,4,196,41,2,28,249,22,128,4,23,197,2,23,195,4,248,22, -90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249,22, -80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23,199, -1,248,22,181,3,23,201,1,250,2,55,23,196,4,196,248,22,181,3,198,28, -249,22,128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7,47, -249,22,157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2,39, -23,200,2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248,22, -156,7,23,195,2,250,2,55,23,196,4,23,197,1,39,2,27,248,22,181,3, -23,197,1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249,22, -136,9,7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175,7, -23,200,2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181,3, -23,199,1,250,2,54,23,197,4,197,248,22,181,3,196,32,70,88,148,39,40, -58,11,2,31,222,33,71,28,248,22,88,248,22,82,23,195,2,249,22,7,9, -248,22,162,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,163,20, -23,197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,162,20, -195,90,144,41,11,89,146,41,39,11,27,248,22,163,20,196,28,248,22,88,248, -22,82,23,195,2,249,22,7,9,248,22,162,20,195,90,144,41,11,89,146,41, -39,11,248,2,70,248,22,163,20,196,249,22,7,249,22,80,248,22,162,20,199, -196,195,249,22,7,249,22,80,248,22,162,20,199,196,195,249,22,7,249,22,80, -248,22,162,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23,196, -2,250,2,54,23,196,4,23,198,1,39,2,28,23,195,1,192,28,248,22,88, -248,22,82,23,195,2,249,22,7,9,248,22,162,20,23,196,1,27,248,22,163, -20,23,195,2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23, -197,2,249,22,7,9,248,22,162,20,23,198,1,27,248,22,163,20,23,197,2, -90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23,197,2,249,22, -7,9,248,22,162,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248,22, -163,20,198,249,22,7,249,22,80,248,22,162,20,201,196,195,249,22,7,249,22, -80,248,22,162,20,23,203,1,196,195,249,22,7,249,22,80,248,22,162,20,23, -201,1,23,197,1,23,196,1,248,22,143,12,252,22,162,10,248,22,163,4,23, -200,2,248,22,159,4,23,200,2,248,22,160,4,23,200,2,248,22,161,4,23, -200,2,248,22,162,4,23,200,1,28,24,194,2,12,20,13,144,80,144,39,41, -40,80,143,39,59,89,146,40,40,10,249,22,130,5,21,94,2,32,6,19,19, -112,108,97,110,101,116,47,114,101,115,111,108,118,101,114,46,114,107,116,1,27, -112,108,97,110,101,116,45,109,111,100,117,108,101,45,110,97,109,101,45,114,101, -115,111,108,118,101,114,12,27,28,23,195,2,28,249,22,169,9,23,197,2,80, -143,42,55,86,94,23,195,1,80,143,40,56,27,248,22,153,5,23,197,2,27, -28,248,22,78,23,195,2,248,22,162,20,23,195,1,23,194,1,28,248,22,174, -15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86, -95,20,18,144,11,80,143,45,55,199,20,18,144,11,80,143,45,56,192,192,11, -11,28,23,193,2,192,86,94,23,193,1,27,247,22,177,5,28,23,193,2,192, -86,94,23,193,1,247,22,152,16,90,144,42,11,89,146,42,39,11,248,22,131, -16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,167,16,0,11,35,114, -120,34,91,46,93,115,115,36,34,248,22,179,15,23,197,1,249,80,144,44,61, -42,23,199,1,2,26,196,249,80,144,41,57,42,195,10,249,22,12,23,196,1, -80,144,41,54,41,86,96,28,248,22,151,5,23,196,2,12,250,22,181,11,2, -22,6,21,21,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45,112, -97,116,104,63,23,198,2,28,28,23,196,2,248,22,145,14,23,197,2,10,12, -250,22,181,11,2,22,6,20,20,40,111,114,47,99,32,35,102,32,110,97,109, -101,115,112,97,99,101,63,41,23,199,2,28,24,193,2,248,24,194,1,23,196, -2,86,94,23,193,1,12,27,250,22,158,2,80,144,44,44,41,248,22,128,17, -247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249,22, -80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,46,44,41,248, -22,128,17,247,22,144,14,195,192,86,94,250,22,156,2,248,22,81,23,197,2, -23,200,2,70,100,101,99,108,97,114,101,100,28,23,198,2,27,28,248,22,78, -248,22,153,5,23,200,2,248,22,152,5,248,22,81,248,22,153,5,23,201,1, -23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,128,17,23,204,1,11, -28,23,193,2,27,250,22,158,2,248,22,82,23,198,1,23,198,2,11,28,23, -193,2,250,22,156,2,248,22,163,20,23,200,1,23,198,1,23,196,1,12,12, -12,86,94,251,22,138,12,247,22,142,12,67,101,114,114,111,114,6,69,69,100, -101,102,97,117,108,116,32,109,111,100,117,108,101,32,110,97,109,101,32,114,101, -115,111,108,118,101,114,32,99,97,108,108,101,100,32,119,105,116,104,32,116,104, -114,101,101,32,97,114,103,117,109,101,110,116,115,32,40,100,101,112,114,101,99, -97,116,101,100,41,11,251,24,197,1,23,198,1,23,199,1,23,200,1,10,32, -81,88,148,39,41,50,11,78,102,108,97,116,116,101,110,45,115,117,98,45,112, -97,116,104,222,33,84,32,82,88,148,39,43,57,11,2,31,222,33,83,28,248, -22,88,23,197,2,28,248,22,88,195,192,249,22,80,194,248,22,95,197,28,249, -22,171,9,248,22,81,23,199,2,2,35,28,248,22,88,23,196,2,86,95,23, -196,1,23,195,1,250,22,177,11,2,22,6,37,37,116,111,111,32,109,97,110, -121,32,34,46,46,34,115,32,105,110,32,115,117,98,109,111,100,117,108,101,32, -112,97,116,104,58,32,126,46,115,250,22,91,2,34,28,249,22,171,9,23,201, -2,2,36,23,199,1,28,248,22,174,15,23,200,2,23,199,1,249,22,90,28, -248,22,64,23,202,2,2,5,2,37,23,201,1,23,200,1,251,2,82,196,197, -248,22,82,199,248,22,163,20,200,251,2,82,196,197,249,22,80,248,22,162,20, -202,200,248,22,163,20,200,251,2,82,196,197,9,197,27,250,22,176,7,27,28, -23,199,2,28,247,22,130,12,248,80,144,47,58,42,23,200,2,11,11,28,192, -192,6,29,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110, -97,109,101,45,114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,178,16, -0,7,35,114,120,34,92,110,34,23,203,1,249,22,137,8,6,23,23,10,32, -32,102,111,114,32,109,111,100,117,108,101,32,112,97,116,104,58,32,126,115,10, -23,202,2,248,22,173,13,28,23,196,2,251,22,181,12,23,198,1,247,22,27, -248,22,90,23,201,1,23,199,1,86,94,23,196,1,250,22,144,13,23,197,1, -247,22,27,23,198,1,32,86,88,148,8,36,40,53,11,69,115,115,45,62,114, -107,116,222,33,87,19,248,22,156,7,194,28,249,22,132,4,23,195,4,42,28, -249,22,169,9,7,46,249,22,157,7,197,249,22,184,3,23,199,4,42,28,28, -249,22,169,9,7,115,249,22,157,7,197,249,22,184,3,23,199,4,41,249,22, -169,9,7,115,249,22,157,7,197,249,22,184,3,23,199,4,40,11,249,22,176, -7,250,22,175,7,198,39,249,22,184,3,23,200,4,42,2,40,193,193,193,2, -28,249,22,159,7,194,2,36,2,27,28,249,22,159,7,194,2,35,64,117,112, -192,0,8,35,114,120,34,91,46,93,34,32,90,88,148,8,36,40,50,11,2, -31,222,33,91,28,248,22,88,23,194,2,9,250,22,91,6,4,4,10,32,32, -32,248,22,178,15,248,22,103,23,198,2,248,2,90,248,22,163,20,23,198,1, -28,249,22,171,9,248,22,82,23,200,2,23,197,1,28,249,22,169,9,248,22, -162,20,23,200,1,23,196,1,251,22,177,11,2,22,6,41,41,99,121,99,108, -101,32,105,110,32,108,111,97,100,105,110,103,10,32,32,97,116,32,112,97,116, -104,58,32,126,97,10,32,32,112,97,116,104,115,58,126,97,23,200,1,249,22, -1,22,176,7,248,2,90,248,22,95,23,201,1,12,12,247,23,193,1,250,22, -157,4,11,196,195,20,13,144,80,144,49,53,41,249,22,80,249,22,80,23,198, -1,23,202,1,23,195,1,20,13,144,80,144,49,41,40,252,80,144,54,42,40, -249,22,31,11,80,144,56,41,40,22,191,4,23,201,2,22,129,5,248,28,23, -208,2,20,20,94,88,148,8,36,40,49,11,9,223,15,33,94,23,208,1,86, -94,23,208,1,22,7,28,248,22,64,23,207,2,23,206,1,28,28,248,22,78, -23,207,2,249,22,169,9,248,22,162,20,23,209,2,2,32,11,23,206,1,86, -94,23,206,1,28,248,22,151,5,23,203,2,27,248,22,153,5,23,204,2,28, -248,22,64,193,249,22,90,2,5,194,192,23,202,2,249,247,22,176,5,23,201, -1,27,248,22,68,248,22,178,15,23,202,1,28,23,204,2,28,250,22,158,2, -248,22,162,20,23,202,1,23,202,1,11,249,22,80,11,205,249,22,80,194,205, -192,86,96,28,248,22,161,5,23,196,2,12,28,248,22,155,4,23,198,2,250, -22,179,11,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116, -104,23,200,2,250,22,181,11,2,22,2,33,23,198,2,28,28,23,196,2,248, -22,151,5,23,197,2,10,12,250,22,181,11,2,22,6,31,31,40,111,114,47, -99,32,35,102,32,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, -112,97,116,104,63,41,23,199,2,28,28,23,197,2,248,22,155,4,23,198,2, -10,12,250,22,181,11,2,22,6,17,17,40,111,114,47,99,32,35,102,32,115, -121,110,116,97,120,63,41,23,200,2,28,28,248,22,78,23,196,2,249,22,169, -9,248,22,162,20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23,196, -1,23,193,1,248,22,152,5,248,22,102,23,197,1,28,28,248,22,78,23,196, -2,28,249,22,169,9,248,22,162,20,23,198,2,2,34,28,248,22,78,248,22, -102,23,197,2,249,22,169,9,248,22,106,23,198,2,2,5,11,11,11,86,97, -23,198,1,23,197,1,23,196,1,23,193,1,248,22,152,5,249,2,81,248,22, -119,23,199,2,248,22,104,23,199,1,28,28,248,22,78,23,196,2,28,249,22, -169,9,248,22,162,20,23,198,2,2,34,28,28,249,22,171,9,248,22,102,23, -198,2,2,36,10,249,22,171,9,248,22,102,23,198,2,2,35,28,23,196,2, -27,248,22,153,5,23,198,2,28,248,22,64,193,10,28,248,22,78,193,248,22, -64,248,22,162,20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23,193, -1,27,248,22,153,5,23,198,1,248,22,152,5,249,2,81,28,248,22,78,23, -197,2,248,22,162,20,23,197,2,23,196,2,27,28,249,22,171,9,248,22,102, -23,203,2,2,35,248,22,163,20,200,248,22,104,200,28,248,22,78,23,198,2, -249,22,94,248,22,163,20,199,194,192,28,28,248,22,78,23,196,2,249,22,169, -9,248,22,162,20,23,198,2,2,38,11,86,94,248,80,144,41,8,28,42,23, -194,2,253,24,199,1,23,201,1,23,202,1,23,203,1,23,204,1,11,80,143, -46,59,28,28,248,22,78,23,196,2,28,249,22,169,9,248,22,162,20,23,198, -2,2,34,28,248,22,78,248,22,102,23,197,2,249,22,169,9,248,22,106,23, -198,2,2,38,11,11,11,86,94,248,80,144,41,8,28,42,23,194,2,253,24, -199,1,248,22,102,23,202,2,23,202,1,23,203,1,23,204,1,248,22,104,23, -202,1,80,143,46,59,86,94,23,193,1,27,88,148,8,36,40,57,8,240,0, -0,8,0,1,19,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110,45, -101,114,114,225,2,5,3,33,85,27,28,248,22,78,23,198,2,28,249,22,169, -9,2,34,248,22,162,20,23,200,2,27,248,22,102,23,199,2,28,28,249,22, -171,9,23,195,2,2,36,10,249,22,171,9,23,195,2,2,35,86,94,23,193, -1,28,23,199,2,27,248,22,153,5,23,201,2,28,248,22,78,193,248,22,162, -20,193,192,250,22,177,11,2,22,6,45,45,110,111,32,98,97,115,101,32,112, -97,116,104,32,102,111,114,32,114,101,108,97,116,105,118,101,32,115,117,98,109, -111,100,117,108,101,32,112,97,116,104,58,32,126,46,115,23,201,2,192,23,197, -2,23,197,2,27,28,248,22,78,23,199,2,28,249,22,169,9,2,34,248,22, -162,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23,202,2,2,36, -10,249,22,171,9,248,22,102,23,202,2,2,35,23,200,2,11,27,248,22,153, -5,23,202,2,27,28,249,22,171,9,248,22,102,23,204,2,2,35,248,22,163, -20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2,249,2,81,248, -22,162,20,23,197,2,249,22,94,248,22,163,20,23,199,1,23,197,1,249,2, -81,23,196,1,23,195,1,249,2,81,2,36,28,249,22,171,9,248,22,102,23, -204,2,2,35,248,22,163,20,23,202,1,248,22,104,23,202,1,28,248,22,78, -193,248,22,163,20,193,11,11,11,27,28,248,22,64,23,196,2,27,248,80,144, -46,51,42,249,22,80,23,199,2,248,22,128,17,247,22,144,14,28,23,193,2, -192,86,94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,49,57,42, -248,22,71,23,201,2,11,27,28,248,22,88,23,195,2,2,39,249,22,176,7, -23,197,2,2,40,252,80,144,53,8,23,42,23,205,1,28,248,22,88,23,200, -2,23,200,1,86,94,23,200,1,248,22,81,23,200,2,28,248,22,88,23,200, -2,86,94,23,199,1,9,248,22,82,23,200,1,23,198,1,10,28,248,22,153, -7,23,196,2,86,94,23,196,1,27,248,80,144,46,8,29,42,23,202,2,27, -248,80,144,47,51,42,249,22,80,23,200,2,23,197,2,28,23,193,2,192,86, -94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,50,57,42,23,201, -2,11,28,248,22,88,23,194,2,86,94,23,193,1,249,22,128,16,23,198,1, -248,2,86,23,197,1,250,22,1,22,128,16,23,199,1,249,22,94,249,22,2, -32,0,88,148,8,36,40,47,11,9,222,33,88,23,200,1,248,22,90,248,2, -86,23,201,1,28,248,22,174,15,23,196,2,86,94,23,196,1,248,80,144,45, -8,30,42,248,22,138,16,28,248,22,135,16,23,198,2,23,197,2,249,22,136, -16,23,199,2,248,80,144,49,8,29,42,23,205,2,28,249,22,169,9,248,22, -81,23,198,2,2,32,27,248,80,144,46,51,42,249,22,80,23,199,2,248,22, -128,17,247,22,144,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11,89, -146,41,39,11,249,80,144,49,57,42,248,22,102,23,201,2,11,27,28,248,22, -88,248,22,104,23,201,2,28,248,22,88,23,195,2,249,22,171,16,2,89,23, -197,2,11,10,27,28,23,194,2,248,2,86,23,197,2,28,248,22,88,23,196, -2,2,39,28,249,22,171,16,2,89,23,198,2,248,2,86,23,197,2,249,22, -176,7,23,198,2,2,40,27,28,23,195,1,86,94,23,197,1,249,22,94,28, -248,22,88,248,22,104,23,205,2,21,93,6,5,5,109,122,108,105,98,249,22, -1,22,94,249,22,2,80,144,56,8,31,42,248,22,104,23,208,2,23,198,1, -28,248,22,88,23,197,2,86,94,23,196,1,248,22,90,23,198,1,86,94,23, -197,1,23,196,1,252,80,144,55,8,23,42,23,207,1,248,22,81,23,199,2, -248,22,163,20,23,199,1,23,199,1,10,28,249,22,169,9,248,22,162,20,23, -198,2,2,37,248,80,144,45,8,30,42,248,22,138,16,249,22,136,16,248,22, -140,16,248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86,94, -28,28,248,22,174,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23,201, -2,250,22,179,11,69,114,101,113,117,105,114,101,249,22,137,8,6,17,17,98, -97,100,32,109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2,248, -22,81,23,199,2,6,0,0,23,204,2,250,22,181,11,2,22,2,33,23,198, -2,27,28,248,22,184,8,23,195,2,249,22,189,8,23,196,2,39,249,22,138, -16,248,22,139,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22,189, -8,23,197,2,40,248,80,144,47,8,24,42,23,195,2,90,144,42,11,89,146, -42,39,11,28,248,22,184,8,23,199,2,250,22,7,2,41,249,22,189,8,23, -203,2,41,2,41,248,22,131,16,23,198,2,86,95,23,195,1,23,193,1,27, -28,248,22,184,8,23,200,2,249,22,189,8,23,201,2,42,249,80,144,52,61, -42,23,197,2,5,0,27,28,248,22,184,8,23,201,2,249,22,189,8,23,202, -2,43,248,22,152,5,23,200,2,27,250,22,158,2,80,144,55,44,41,248,22, -128,17,247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27, -249,22,80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,57,44, -41,248,22,128,17,247,22,144,14,195,192,27,28,23,204,2,248,22,152,5,249, -22,80,248,22,153,5,23,200,2,23,207,2,23,196,2,86,95,28,23,212,2, -28,250,22,158,2,248,22,81,23,198,2,195,11,86,96,23,211,1,23,204,1, -23,194,1,12,27,251,22,31,11,80,144,59,53,41,9,28,248,22,15,80,144, -60,54,41,80,144,59,54,41,247,22,17,27,248,22,128,17,247,22,144,14,86, -94,249,22,3,88,148,8,36,40,57,11,9,226,13,12,2,3,33,92,23,196, -2,248,28,248,22,15,80,144,58,54,41,32,0,88,148,39,40,45,11,9,222, -33,93,80,144,57,8,32,42,20,20,98,88,148,39,39,8,25,8,240,12,64, -0,0,9,233,18,21,14,15,12,11,7,6,4,1,2,33,95,23,195,1,23, -194,1,23,197,1,23,207,1,23,214,1,12,28,28,248,22,184,8,23,204,1, -86,94,23,212,1,11,28,23,212,1,28,248,22,153,7,23,206,2,10,28,248, -22,64,23,206,2,10,28,248,22,78,23,206,2,249,22,169,9,248,22,162,20, -23,208,2,2,32,11,11,249,80,144,56,52,42,28,248,22,153,7,23,208,2, -249,22,80,23,209,1,248,80,144,59,8,29,42,23,215,1,86,94,23,212,1, -249,22,80,23,209,1,248,22,128,17,247,22,144,14,252,22,186,8,23,209,1, -23,208,1,23,206,1,23,204,1,23,203,1,12,192,86,96,20,18,144,11,80, -143,39,59,248,80,144,40,8,27,40,249,22,31,11,80,144,42,41,40,248,22, -190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,143,15,80, -144,40,48,42,20,18,144,11,80,143,39,59,248,80,144,40,8,27,40,249,22, -31,11,80,144,42,41,40,20,18,144,11,80,143,39,59,248,80,144,40,8,27, -40,249,22,31,11,80,144,42,41,40,144,39,20,121,145,2,1,39,16,1,11, -16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9, -11,11,11,10,41,80,143,39,39,20,121,145,2,1,44,16,28,2,3,2,4, -30,2,6,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110, -45,107,101,121,11,6,30,2,6,1,23,101,120,116,101,110,100,45,112,97,114, -97,109,101,116,101,114,105,122,97,116,105,111,110,11,4,30,2,7,74,112,97, -116,104,45,115,116,114,105,110,103,63,42,196,15,2,8,30,2,7,73,114,101, -114,111,111,116,45,112,97,116,104,44,196,16,30,2,7,77,112,97,116,104,45, -97,100,100,45,115,117,102,102,105,120,44,196,12,2,9,2,10,2,11,2,12, -2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22,30, -2,7,1,19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102, -105,120,44,196,14,30,2,7,75,102,105,110,100,45,99,111,108,45,102,105,108, -101,49,196,4,30,2,7,78,110,111,114,109,97,108,45,99,97,115,101,45,112, -97,116,104,42,196,11,2,23,2,24,30,2,6,76,114,101,112,97,114,97,109, -101,116,101,114,105,122,101,11,7,16,0,40,42,39,16,0,39,16,16,2,15, -2,16,2,8,2,12,2,17,2,18,2,11,2,4,2,10,2,3,2,20,2, -13,2,14,2,9,2,19,2,22,55,11,11,11,16,3,2,23,2,21,2,24, -16,3,11,11,11,16,3,2,23,2,21,2,24,42,42,40,12,11,11,16,0, -16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,24,20, -15,16,2,248,22,180,8,71,115,111,45,115,117,102,102,105,120,80,144,39,39, -40,20,15,16,2,88,148,39,41,8,39,8,189,3,2,4,223,0,33,50,80, -144,39,40,40,20,15,16,2,32,0,88,148,8,36,44,55,11,2,9,222,33, -51,80,144,39,47,40,20,15,16,2,20,28,143,32,0,88,148,8,36,40,45, -11,2,10,222,192,32,0,88,148,8,36,40,45,11,2,10,222,192,80,144,39, -48,40,20,15,16,2,247,22,141,2,80,144,39,44,40,20,15,16,2,8,128, -8,80,144,39,49,40,20,15,16,2,249,22,185,8,8,128,8,11,80,144,39, -50,40,20,15,16,2,88,148,8,36,40,53,8,128,32,2,13,223,0,33,52, -80,144,39,51,40,20,15,16,2,88,148,8,36,41,57,8,128,32,2,14,223, -0,33,53,80,144,39,52,40,20,15,16,2,247,22,76,80,144,39,53,40,20, -15,16,2,248,22,16,76,109,111,100,117,108,101,45,108,111,97,100,105,110,103, -80,144,39,54,40,20,15,16,2,11,80,143,39,55,20,15,16,2,11,80,143, -39,56,20,15,16,2,32,0,88,148,39,41,60,11,2,19,222,33,72,80,144, -39,57,40,20,15,16,2,32,0,88,148,8,36,40,52,11,2,20,222,33,73, -80,144,39,58,40,20,15,16,2,11,80,143,39,59,20,15,16,2,88,149,8, -34,40,48,8,240,4,0,16,0,1,21,112,114,101,112,45,112,108,97,110,101, -116,45,114,101,115,111,108,118,101,114,33,40,224,1,0,33,74,80,144,39,8, -28,42,20,15,16,2,88,148,39,40,53,8,240,0,0,3,0,69,103,101,116, -45,100,105,114,223,0,33,75,80,144,39,8,29,42,20,15,16,2,88,148,39, -40,52,8,240,0,0,64,0,74,112,97,116,104,45,115,115,45,62,114,107,116, -223,0,33,76,80,144,39,8,30,42,20,15,16,2,88,148,8,36,40,48,8, -240,0,0,4,0,9,223,0,33,77,80,144,39,8,31,42,20,15,16,2,88, -148,39,40,48,8,240,0,128,0,0,9,223,0,33,78,80,144,39,8,32,42, -20,15,16,2,27,11,20,19,143,39,90,144,40,10,89,146,40,39,10,20,26, -96,2,22,88,148,8,36,41,57,8,32,9,224,2,1,33,79,88,148,39,42, -52,11,9,223,0,33,80,88,148,39,43,8,32,16,4,8,240,44,240,0,0, -8,240,220,241,0,0,40,39,9,224,2,1,33,96,207,80,144,39,60,40,20, -15,16,2,88,148,39,39,48,16,2,8,134,8,8,176,32,2,23,223,0,33, -97,80,144,39,8,25,40,20,15,16,2,20,28,143,88,148,8,36,39,48,16, -2,43,8,144,32,2,24,223,0,33,98,88,148,8,36,39,48,16,2,43,8, -144,32,2,24,223,0,33,99,80,144,39,8,26,40,96,29,94,2,5,70,35, -37,107,101,114,110,101,108,11,29,94,2,5,71,35,37,109,105,110,45,115,116, -120,11,2,7,2,6,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 9713); +199,1,248,22,181,3,23,201,1,250,2,64,23,196,4,196,248,22,181,3,198, +28,249,22,128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7, +47,249,22,157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2, +39,23,200,2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248, +22,156,7,23,195,2,250,2,60,23,196,4,23,197,1,39,2,27,248,22,181, +3,23,197,1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249, +22,136,9,7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175, +7,23,200,2,39,23,198,2,27,249,22,175,7,23,200,1,248,22,181,3,23, +199,1,19,248,22,156,7,23,195,2,250,2,64,23,196,4,23,197,1,39,2, +27,248,22,181,3,23,195,1,28,249,22,128,4,23,195,2,23,197,4,248,22, +90,196,28,249,22,136,9,7,47,249,22,157,7,23,200,2,23,197,2,249,22, +80,250,22,175,7,23,201,2,39,23,198,2,248,2,56,249,22,175,7,23,201, +1,248,22,181,3,23,199,1,250,2,59,23,198,4,198,248,22,181,3,196,19, +248,22,156,7,23,195,2,28,249,22,128,4,39,23,195,4,248,22,90,194,28, +249,22,136,9,7,47,249,22,157,7,23,198,2,39,249,22,80,250,22,175,7, +23,199,2,39,39,27,249,22,175,7,23,199,1,40,19,248,22,156,7,23,195, +2,250,2,57,23,196,4,23,197,1,39,2,28,249,22,128,4,40,23,195,4, +248,22,90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,40,249,22, +80,250,22,175,7,23,199,2,39,40,248,2,56,249,22,175,7,23,199,1,41, +250,2,59,23,196,4,196,41,2,28,249,22,128,4,23,197,2,23,195,4,248, +22,90,194,28,249,22,136,9,7,47,249,22,157,7,23,198,2,23,199,2,249, +22,80,250,22,175,7,23,199,2,39,23,200,2,248,2,56,249,22,175,7,23, +199,1,248,22,181,3,23,201,1,250,2,55,23,196,4,196,248,22,181,3,198, +28,249,22,128,4,23,197,2,23,195,4,248,22,90,194,28,249,22,136,9,7, +47,249,22,157,7,23,198,2,23,199,2,249,22,80,250,22,175,7,23,199,2, +39,23,200,2,27,249,22,175,7,23,199,1,248,22,181,3,23,201,1,19,248, +22,156,7,23,195,2,250,2,55,23,196,4,23,197,1,39,2,27,248,22,181, +3,23,197,1,28,249,22,128,4,23,195,2,23,196,4,248,22,90,195,28,249, +22,136,9,7,47,249,22,157,7,23,199,2,23,197,2,249,22,80,250,22,175, +7,23,200,2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181, +3,23,199,1,250,2,54,23,197,4,197,248,22,181,3,196,32,70,88,148,39, +40,58,11,2,31,222,33,71,28,248,22,88,248,22,82,23,195,2,249,22,7, +9,248,22,163,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,164, +20,23,197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,163, +20,195,90,144,41,11,89,146,41,39,11,27,248,22,164,20,196,28,248,22,88, +248,22,82,23,195,2,249,22,7,9,248,22,163,20,195,90,144,41,11,89,146, +41,39,11,248,2,70,248,22,164,20,196,249,22,7,249,22,80,248,22,163,20, +199,196,195,249,22,7,249,22,80,248,22,163,20,199,196,195,249,22,7,249,22, +80,248,22,163,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23, +196,2,250,2,54,23,196,4,23,198,1,39,2,28,23,195,1,192,28,248,22, +88,248,22,82,23,195,2,249,22,7,9,248,22,163,20,23,196,1,27,248,22, +164,20,23,195,2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82, +23,197,2,249,22,7,9,248,22,163,20,23,198,1,27,248,22,164,20,23,197, +2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23,197,2,249, +22,7,9,248,22,163,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248, +22,164,20,198,249,22,7,249,22,80,248,22,163,20,201,196,195,249,22,7,249, +22,80,248,22,163,20,23,203,1,196,195,249,22,7,249,22,80,248,22,163,20, +23,201,1,23,197,1,23,196,1,248,22,143,12,252,22,162,10,248,22,163,4, +23,200,2,248,22,159,4,23,200,2,248,22,160,4,23,200,2,248,22,161,4, +23,200,2,248,22,162,4,23,200,1,28,24,194,2,12,20,13,144,80,144,39, +41,40,80,143,39,59,89,146,40,40,10,249,22,130,5,21,94,2,32,6,19, +19,112,108,97,110,101,116,47,114,101,115,111,108,118,101,114,46,114,107,116,1, +27,112,108,97,110,101,116,45,109,111,100,117,108,101,45,110,97,109,101,45,114, +101,115,111,108,118,101,114,12,27,28,23,195,2,28,249,22,169,9,23,197,2, +80,143,42,55,86,94,23,195,1,80,143,40,56,27,248,22,153,5,23,197,2, +27,28,248,22,78,23,195,2,248,22,163,20,23,195,1,23,194,1,28,248,22, +174,15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1, +86,95,20,18,144,11,80,143,45,55,199,20,18,144,11,80,143,45,56,192,192, +11,11,28,23,193,2,192,86,94,23,193,1,27,247,22,177,5,28,23,193,2, +192,86,94,23,193,1,247,22,152,16,90,144,42,11,89,146,42,39,11,248,22, +131,16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,167,16,0,11,35, +114,120,34,91,46,93,115,115,36,34,248,22,179,15,23,197,1,249,80,144,44, +61,42,23,199,1,2,26,196,249,80,144,41,57,42,195,10,249,22,12,23,196, +1,80,144,41,54,41,86,96,28,248,22,151,5,23,196,2,12,250,22,181,11, +2,22,6,21,21,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, +112,97,116,104,63,23,198,2,28,28,23,196,2,248,22,145,14,23,197,2,10, +12,250,22,181,11,2,22,6,20,20,40,111,114,47,99,32,35,102,32,110,97, +109,101,115,112,97,99,101,63,41,23,199,2,28,24,193,2,248,24,194,1,23, +196,2,86,94,23,193,1,12,27,250,22,158,2,80,144,44,44,41,248,22,128, +17,247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249, +22,80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,46,44,41, +248,22,128,17,247,22,144,14,195,192,86,94,250,22,156,2,248,22,81,23,197, +2,23,200,2,70,100,101,99,108,97,114,101,100,28,23,198,2,27,28,248,22, +78,248,22,153,5,23,200,2,248,22,152,5,248,22,81,248,22,153,5,23,201, +1,23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,128,17,23,204,1, +11,28,23,193,2,27,250,22,158,2,248,22,82,23,198,1,23,198,2,11,28, +23,193,2,250,22,156,2,248,22,164,20,23,200,1,23,198,1,23,196,1,12, +12,12,86,94,251,22,138,12,247,22,142,12,67,101,114,114,111,114,6,69,69, +100,101,102,97,117,108,116,32,109,111,100,117,108,101,32,110,97,109,101,32,114, +101,115,111,108,118,101,114,32,99,97,108,108,101,100,32,119,105,116,104,32,116, +104,114,101,101,32,97,114,103,117,109,101,110,116,115,32,40,100,101,112,114,101, +99,97,116,101,100,41,11,251,24,197,1,23,198,1,23,199,1,23,200,1,10, +32,81,88,148,39,41,50,11,78,102,108,97,116,116,101,110,45,115,117,98,45, +112,97,116,104,222,33,84,32,82,88,148,39,43,57,11,2,31,222,33,83,28, +248,22,88,23,197,2,28,248,22,88,195,192,249,22,80,194,248,22,95,197,28, +249,22,171,9,248,22,81,23,199,2,2,35,28,248,22,88,23,196,2,86,95, +23,196,1,23,195,1,250,22,177,11,2,22,6,37,37,116,111,111,32,109,97, +110,121,32,34,46,46,34,115,32,105,110,32,115,117,98,109,111,100,117,108,101, +32,112,97,116,104,58,32,126,46,115,250,22,91,2,34,28,249,22,171,9,23, +201,2,2,36,23,199,1,28,248,22,174,15,23,200,2,23,199,1,249,22,90, +28,248,22,64,23,202,2,2,5,2,37,23,201,1,23,200,1,251,2,82,196, +197,248,22,82,199,248,22,164,20,200,251,2,82,196,197,249,22,80,248,22,163, +20,202,200,248,22,164,20,200,251,2,82,196,197,9,197,27,250,22,176,7,27, +28,23,199,2,28,247,22,130,12,248,80,144,47,58,42,23,200,2,11,11,28, +192,192,6,29,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45, +110,97,109,101,45,114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,178, +16,0,7,35,114,120,34,92,110,34,23,203,1,249,22,137,8,6,23,23,10, +32,32,102,111,114,32,109,111,100,117,108,101,32,112,97,116,104,58,32,126,115, +10,23,202,2,248,22,173,13,28,23,196,2,251,22,181,12,23,198,1,247,22, +27,248,22,90,23,201,1,23,199,1,86,94,23,196,1,250,22,144,13,23,197, +1,247,22,27,23,198,1,32,86,88,148,8,36,40,53,11,69,115,115,45,62, +114,107,116,222,33,87,19,248,22,156,7,194,28,249,22,132,4,23,195,4,42, +28,249,22,169,9,7,46,249,22,157,7,197,249,22,184,3,23,199,4,42,28, +28,249,22,169,9,7,115,249,22,157,7,197,249,22,184,3,23,199,4,41,249, +22,169,9,7,115,249,22,157,7,197,249,22,184,3,23,199,4,40,11,249,22, +176,7,250,22,175,7,198,39,249,22,184,3,23,200,4,42,2,40,193,193,193, +2,28,249,22,159,7,194,2,36,2,27,28,249,22,159,7,194,2,35,64,117, +112,192,0,8,35,114,120,34,91,46,93,34,32,90,88,148,8,36,40,50,11, +2,31,222,33,91,28,248,22,88,23,194,2,9,250,22,91,6,4,4,10,32, +32,32,248,22,178,15,248,22,103,23,198,2,248,2,90,248,22,164,20,23,198, +1,28,249,22,171,9,248,22,82,23,200,2,23,197,1,28,249,22,169,9,248, +22,163,20,23,200,1,23,196,1,251,22,177,11,2,22,6,41,41,99,121,99, +108,101,32,105,110,32,108,111,97,100,105,110,103,10,32,32,97,116,32,112,97, +116,104,58,32,126,97,10,32,32,112,97,116,104,115,58,126,97,23,200,1,249, +22,1,22,176,7,248,2,90,248,22,95,23,201,1,12,12,247,23,193,1,250, +22,157,4,11,196,195,20,13,144,80,144,49,53,41,249,22,80,249,22,80,23, +198,1,23,202,1,23,195,1,20,13,144,80,144,49,41,40,252,80,144,54,42, +40,249,22,31,11,80,144,56,41,40,22,191,4,23,201,2,22,129,5,248,28, +23,208,2,20,20,94,88,148,8,36,40,49,11,9,223,15,33,94,23,208,1, +86,94,23,208,1,22,7,28,248,22,64,23,207,2,23,206,1,28,28,248,22, +78,23,207,2,249,22,169,9,248,22,163,20,23,209,2,2,32,11,23,206,1, +86,94,23,206,1,28,248,22,151,5,23,203,2,27,248,22,153,5,23,204,2, +28,248,22,64,193,249,22,90,2,5,194,192,23,202,2,249,247,22,176,5,23, +201,1,27,248,22,68,248,22,178,15,23,202,1,28,23,204,2,28,250,22,158, +2,248,22,163,20,23,202,1,23,202,1,11,249,22,80,11,205,249,22,80,194, +205,192,86,96,28,248,22,161,5,23,196,2,12,28,248,22,155,4,23,198,2, +250,22,179,11,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97, +116,104,23,200,2,250,22,181,11,2,22,2,33,23,198,2,28,28,23,196,2, +248,22,151,5,23,197,2,10,12,250,22,181,11,2,22,6,31,31,40,111,114, +47,99,32,35,102,32,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101, +45,112,97,116,104,63,41,23,199,2,28,28,23,197,2,248,22,155,4,23,198, +2,10,12,250,22,181,11,2,22,6,17,17,40,111,114,47,99,32,35,102,32, +115,121,110,116,97,120,63,41,23,200,2,28,28,248,22,78,23,196,2,249,22, +169,9,248,22,163,20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23, +196,1,23,193,1,248,22,152,5,248,22,102,23,197,1,28,28,248,22,78,23, +196,2,28,249,22,169,9,248,22,163,20,23,198,2,2,34,28,248,22,78,248, +22,102,23,197,2,249,22,169,9,248,22,106,23,198,2,2,5,11,11,11,86, +97,23,198,1,23,197,1,23,196,1,23,193,1,248,22,152,5,249,2,81,248, +22,119,23,199,2,248,22,104,23,199,1,28,28,248,22,78,23,196,2,28,249, +22,169,9,248,22,163,20,23,198,2,2,34,28,28,249,22,171,9,248,22,102, +23,198,2,2,36,10,249,22,171,9,248,22,102,23,198,2,2,35,28,23,196, +2,27,248,22,153,5,23,198,2,28,248,22,64,193,10,28,248,22,78,193,248, +22,64,248,22,163,20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23, +193,1,27,248,22,153,5,23,198,1,248,22,152,5,249,2,81,28,248,22,78, +23,197,2,248,22,163,20,23,197,2,23,196,2,27,28,249,22,171,9,248,22, +102,23,203,2,2,35,248,22,164,20,200,248,22,104,200,28,248,22,78,23,198, +2,249,22,94,248,22,164,20,199,194,192,28,28,248,22,78,23,196,2,249,22, +169,9,248,22,163,20,23,198,2,2,38,11,86,94,248,80,144,41,8,28,42, +23,194,2,253,24,199,1,23,201,1,23,202,1,23,203,1,23,204,1,11,80, +143,46,59,28,28,248,22,78,23,196,2,28,249,22,169,9,248,22,163,20,23, +198,2,2,34,28,248,22,78,248,22,102,23,197,2,249,22,169,9,248,22,106, +23,198,2,2,38,11,11,11,86,94,248,80,144,41,8,28,42,23,194,2,253, +24,199,1,248,22,102,23,202,2,23,202,1,23,203,1,23,204,1,248,22,104, +23,202,1,80,143,46,59,86,94,23,193,1,27,88,148,8,36,40,57,8,240, +0,0,8,0,1,19,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110, +45,101,114,114,225,2,5,3,33,85,27,28,248,22,78,23,198,2,28,249,22, +169,9,2,34,248,22,163,20,23,200,2,27,248,22,102,23,199,2,28,28,249, +22,171,9,23,195,2,2,36,10,249,22,171,9,23,195,2,2,35,86,94,23, +193,1,28,23,199,2,27,248,22,153,5,23,201,2,28,248,22,78,193,248,22, +163,20,193,192,250,22,177,11,2,22,6,45,45,110,111,32,98,97,115,101,32, +112,97,116,104,32,102,111,114,32,114,101,108,97,116,105,118,101,32,115,117,98, +109,111,100,117,108,101,32,112,97,116,104,58,32,126,46,115,23,201,2,192,23, +197,2,23,197,2,27,28,248,22,78,23,199,2,28,249,22,169,9,2,34,248, +22,163,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23,202,2,2, +36,10,249,22,171,9,248,22,102,23,202,2,2,35,23,200,2,11,27,248,22, +153,5,23,202,2,27,28,249,22,171,9,248,22,102,23,204,2,2,35,248,22, +164,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2,249,2,81, +248,22,163,20,23,197,2,249,22,94,248,22,164,20,23,199,1,23,197,1,249, +2,81,23,196,1,23,195,1,249,2,81,2,36,28,249,22,171,9,248,22,102, +23,204,2,2,35,248,22,164,20,23,202,1,248,22,104,23,202,1,28,248,22, +78,193,248,22,164,20,193,11,11,11,27,28,248,22,64,23,196,2,27,248,80, +144,46,51,42,249,22,80,23,199,2,248,22,128,17,247,22,144,14,28,23,193, +2,192,86,94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,49,57, +42,248,22,71,23,201,2,11,27,28,248,22,88,23,195,2,2,39,249,22,176, +7,23,197,2,2,40,252,80,144,53,8,23,42,23,205,1,28,248,22,88,23, +200,2,23,200,1,86,94,23,200,1,248,22,81,23,200,2,28,248,22,88,23, +200,2,86,94,23,199,1,9,248,22,82,23,200,1,23,198,1,10,28,248,22, +153,7,23,196,2,86,94,23,196,1,27,248,80,144,46,8,29,42,23,202,2, +27,248,80,144,47,51,42,249,22,80,23,200,2,23,197,2,28,23,193,2,192, +86,94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,50,57,42,23, +201,2,11,28,248,22,88,23,194,2,86,94,23,193,1,249,22,128,16,23,198, +1,248,2,86,23,197,1,250,22,1,22,128,16,23,199,1,249,22,94,249,22, +2,32,0,88,148,8,36,40,47,11,9,222,33,88,23,200,1,248,22,90,248, +2,86,23,201,1,28,248,22,174,15,23,196,2,86,94,23,196,1,248,80,144, +45,8,30,42,248,22,138,16,28,248,22,135,16,23,198,2,23,197,2,249,22, +136,16,23,199,2,248,80,144,49,8,29,42,23,205,2,28,249,22,169,9,248, +22,81,23,198,2,2,32,27,248,80,144,46,51,42,249,22,80,23,199,2,248, +22,128,17,247,22,144,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11, +89,146,41,39,11,249,80,144,49,57,42,248,22,102,23,201,2,11,27,28,248, +22,88,248,22,104,23,201,2,28,248,22,88,23,195,2,249,22,171,16,2,89, +23,197,2,11,10,27,28,23,194,2,248,2,86,23,197,2,28,248,22,88,23, +196,2,2,39,28,249,22,171,16,2,89,23,198,2,248,2,86,23,197,2,249, +22,176,7,23,198,2,2,40,27,28,23,195,1,86,94,23,197,1,249,22,94, +28,248,22,88,248,22,104,23,205,2,21,93,6,5,5,109,122,108,105,98,249, +22,1,22,94,249,22,2,80,144,56,8,31,42,248,22,104,23,208,2,23,198, +1,28,248,22,88,23,197,2,86,94,23,196,1,248,22,90,23,198,1,86,94, +23,197,1,23,196,1,252,80,144,55,8,23,42,23,207,1,248,22,81,23,199, +2,248,22,164,20,23,199,1,23,199,1,10,28,249,22,169,9,248,22,163,20, +23,198,2,2,37,248,80,144,45,8,30,42,248,22,138,16,249,22,136,16,248, +22,140,16,248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86, +94,28,28,248,22,174,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23, +201,2,250,22,179,11,69,114,101,113,117,105,114,101,249,22,137,8,6,17,17, +98,97,100,32,109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2, +248,22,81,23,199,2,6,0,0,23,204,2,250,22,181,11,2,22,2,33,23, +198,2,27,28,248,22,184,8,23,195,2,249,22,189,8,23,196,2,39,249,22, +138,16,248,22,139,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22, +189,8,23,197,2,40,248,80,144,47,8,24,42,23,195,2,90,144,42,11,89, +146,42,39,11,28,248,22,184,8,23,199,2,250,22,7,2,41,249,22,189,8, +23,203,2,41,2,41,248,22,131,16,23,198,2,86,95,23,195,1,23,193,1, +27,28,248,22,184,8,23,200,2,249,22,189,8,23,201,2,42,249,80,144,52, +61,42,23,197,2,5,0,27,28,248,22,184,8,23,201,2,249,22,189,8,23, +202,2,43,248,22,152,5,23,200,2,27,250,22,158,2,80,144,55,44,41,248, +22,128,17,247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1, +27,249,22,80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,57, +44,41,248,22,128,17,247,22,144,14,195,192,27,28,23,204,2,248,22,152,5, +249,22,80,248,22,153,5,23,200,2,23,207,2,23,196,2,86,95,28,23,212, +2,28,250,22,158,2,248,22,81,23,198,2,195,11,86,96,23,211,1,23,204, +1,23,194,1,12,27,251,22,31,11,80,144,59,53,41,9,28,248,22,15,80, +144,60,54,41,80,144,59,54,41,247,22,17,27,248,22,128,17,247,22,144,14, +86,94,249,22,3,88,148,8,36,40,57,11,9,226,13,12,2,3,33,92,23, +196,2,248,28,248,22,15,80,144,58,54,41,32,0,88,148,39,40,45,11,9, +222,33,93,80,144,57,8,32,42,20,20,98,88,148,39,39,8,25,8,240,12, +64,0,0,9,233,18,21,14,15,12,11,7,6,4,1,2,33,95,23,195,1, +23,194,1,23,197,1,23,207,1,23,214,1,12,28,28,248,22,184,8,23,204, +1,86,94,23,212,1,11,28,23,212,1,28,248,22,153,7,23,206,2,10,28, +248,22,64,23,206,2,10,28,248,22,78,23,206,2,249,22,169,9,248,22,163, +20,23,208,2,2,32,11,11,249,80,144,56,52,42,28,248,22,153,7,23,208, +2,249,22,80,23,209,1,248,80,144,59,8,29,42,23,215,1,86,94,23,212, +1,249,22,80,23,209,1,248,22,128,17,247,22,144,14,252,22,186,8,23,209, +1,23,208,1,23,206,1,23,204,1,23,203,1,12,192,86,96,20,18,144,11, +80,143,39,59,248,80,144,40,8,27,40,249,22,31,11,80,144,42,41,40,248, +22,190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,143,15, +80,144,40,48,42,20,18,144,11,80,143,39,59,248,80,144,40,8,27,40,249, +22,31,11,80,144,42,41,40,20,18,144,11,80,143,39,59,248,80,144,40,8, +27,40,249,22,31,11,80,144,42,41,40,144,39,20,121,145,2,1,39,16,1, +11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9, +9,11,11,11,10,41,80,143,39,39,20,121,145,2,1,44,16,28,2,3,2, +4,30,2,6,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111, +110,45,107,101,121,11,6,30,2,6,1,23,101,120,116,101,110,100,45,112,97, +114,97,109,101,116,101,114,105,122,97,116,105,111,110,11,4,30,2,7,74,112, +97,116,104,45,115,116,114,105,110,103,63,42,196,15,2,8,30,2,7,73,114, +101,114,111,111,116,45,112,97,116,104,44,196,16,30,2,7,77,112,97,116,104, +45,97,100,100,45,115,117,102,102,105,120,44,196,12,2,9,2,10,2,11,2, +12,2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22, +30,2,7,1,19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102, +102,105,120,44,196,14,30,2,7,75,102,105,110,100,45,99,111,108,45,102,105, +108,101,49,196,4,30,2,7,78,110,111,114,109,97,108,45,99,97,115,101,45, +112,97,116,104,42,196,11,2,23,2,24,30,2,6,76,114,101,112,97,114,97, +109,101,116,101,114,105,122,101,11,7,16,0,40,42,39,16,0,39,16,16,2, +15,2,16,2,8,2,12,2,17,2,18,2,11,2,4,2,10,2,3,2,20, +2,13,2,14,2,9,2,19,2,22,55,11,11,11,16,3,2,23,2,21,2, +24,16,3,11,11,11,16,3,2,23,2,21,2,24,42,42,40,12,11,11,16, +0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,24, +20,15,16,2,248,22,180,8,71,115,111,45,115,117,102,102,105,120,80,144,39, +39,40,20,15,16,2,88,148,39,41,8,39,8,189,3,2,4,223,0,33,50, +80,144,39,40,40,20,15,16,2,32,0,88,148,8,36,44,55,11,2,9,222, +33,51,80,144,39,47,40,20,15,16,2,20,28,143,32,0,88,148,8,36,40, +45,11,2,10,222,192,32,0,88,148,8,36,40,45,11,2,10,222,192,80,144, +39,48,40,20,15,16,2,247,22,141,2,80,144,39,44,40,20,15,16,2,8, +128,8,80,144,39,49,40,20,15,16,2,249,22,185,8,8,128,8,11,80,144, +39,50,40,20,15,16,2,88,148,8,36,40,53,8,128,32,2,13,223,0,33, +52,80,144,39,51,40,20,15,16,2,88,148,8,36,41,57,8,128,32,2,14, +223,0,33,53,80,144,39,52,40,20,15,16,2,247,22,76,80,144,39,53,40, +20,15,16,2,248,22,16,76,109,111,100,117,108,101,45,108,111,97,100,105,110, +103,80,144,39,54,40,20,15,16,2,11,80,143,39,55,20,15,16,2,11,80, +143,39,56,20,15,16,2,32,0,88,148,39,41,60,11,2,19,222,33,72,80, +144,39,57,40,20,15,16,2,32,0,88,148,8,36,40,52,11,2,20,222,33, +73,80,144,39,58,40,20,15,16,2,11,80,143,39,59,20,15,16,2,88,149, +8,34,40,48,8,240,4,0,16,0,1,21,112,114,101,112,45,112,108,97,110, +101,116,45,114,101,115,111,108,118,101,114,33,40,224,1,0,33,74,80,144,39, +8,28,42,20,15,16,2,88,148,39,40,53,8,240,0,0,3,0,69,103,101, +116,45,100,105,114,223,0,33,75,80,144,39,8,29,42,20,15,16,2,88,148, +39,40,52,8,240,0,0,64,0,74,112,97,116,104,45,115,115,45,62,114,107, +116,223,0,33,76,80,144,39,8,30,42,20,15,16,2,88,148,8,36,40,48, +8,240,0,0,4,0,9,223,0,33,77,80,144,39,8,31,42,20,15,16,2, +88,148,39,40,48,8,240,0,128,0,0,9,223,0,33,78,80,144,39,8,32, +42,20,15,16,2,27,11,20,19,143,39,90,144,40,10,89,146,40,39,10,20, +26,96,2,22,88,148,8,36,41,57,8,32,9,224,2,1,33,79,88,148,39, +42,52,11,9,223,0,33,80,88,148,39,43,8,32,16,4,8,240,44,240,0, +0,8,240,220,241,0,0,40,39,9,224,2,1,33,96,207,80,144,39,60,40, +20,15,16,2,88,148,39,39,48,16,2,8,134,8,8,176,32,2,23,223,0, +33,97,80,144,39,8,25,40,20,15,16,2,20,28,143,88,148,8,36,39,48, +16,2,43,8,144,32,2,24,223,0,33,98,88,148,8,36,39,48,16,2,43, +8,144,32,2,24,223,0,33,99,80,144,39,8,26,40,96,29,94,2,5,70, +35,37,107,101,114,110,101,108,11,29,94,2,5,71,35,37,109,105,110,45,115, +116,120,11,2,7,2,6,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 9714); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,54,46,50,46,57,48,48,46,57,84,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,1,0,0,8,0, -18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0,135, -0,147,0,231,0,238,0,8,1,0,0,198,1,0,0,3,1,5,105,110,115, -112,48,71,35,37,98,117,105,108,116,105,110,67,113,117,111,116,101,29,94,2, -3,70,35,37,107,101,114,110,101,108,11,29,94,2,3,70,35,37,101,120,112, -111,98,115,11,29,94,2,3,68,35,37,98,111,111,116,11,29,94,2,3,76, -35,37,112,108,97,99,101,45,115,116,114,117,99,116,11,29,94,2,3,70,35, -37,112,97,114,97,109,122,11,29,94,2,3,71,35,37,110,101,116,119,111,114, -107,11,29,94,2,3,69,35,37,117,116,105,108,115,11,38,11,93,2,12,36, -12,0,39,38,13,93,143,16,3,39,2,14,2,2,39,36,14,1,150,40,143, -2,15,16,4,2,4,39,39,2,1,143,2,15,16,4,2,5,39,39,2,1, -143,2,15,16,4,2,6,39,39,2,1,143,2,15,16,4,2,7,39,39,2, -1,143,2,15,16,4,2,8,39,39,2,1,143,2,15,16,4,2,9,39,39, -2,1,143,2,15,16,4,2,10,39,39,2,1,16,0,38,15,143,2,14,2, -11,18,143,16,2,143,10,16,3,9,2,11,2,13,143,11,16,3,9,9,2, -13,16,3,9,9,9,144,39,20,121,145,2,1,39,16,1,11,16,0,20,27, -15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9,11,11,11,33, -16,39,80,143,39,39,20,121,145,2,1,39,16,0,16,0,40,42,39,16,0, -39,16,0,39,11,11,11,16,0,16,0,16,0,39,39,40,12,11,11,16,0, -16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,0,104, -2,4,2,5,29,94,2,3,71,35,37,102,111,114,101,105,103,110,11,29,94, -2,3,70,35,37,117,110,115,97,102,101,11,29,94,2,3,71,35,37,102,108, -102,120,110,117,109,11,2,6,2,7,2,8,2,9,2,10,29,94,2,3,69, -35,37,112,108,97,99,101,11,29,94,2,3,71,35,37,102,117,116,117,114,101, -115,11,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 532); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,1,0,0,8, +0,18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0, +135,0,147,0,231,0,238,0,8,1,0,0,198,1,0,0,3,1,5,105,110, +115,112,48,71,35,37,98,117,105,108,116,105,110,67,113,117,111,116,101,29,94, +2,3,70,35,37,107,101,114,110,101,108,11,29,94,2,3,70,35,37,101,120, +112,111,98,115,11,29,94,2,3,68,35,37,98,111,111,116,11,29,94,2,3, +76,35,37,112,108,97,99,101,45,115,116,114,117,99,116,11,29,94,2,3,70, +35,37,112,97,114,97,109,122,11,29,94,2,3,71,35,37,110,101,116,119,111, +114,107,11,29,94,2,3,69,35,37,117,116,105,108,115,11,38,11,93,2,12, +36,12,0,39,38,13,93,143,16,3,39,2,14,2,2,39,36,14,1,150,40, +143,2,15,16,4,2,4,39,39,2,1,143,2,15,16,4,2,5,39,39,2, +1,143,2,15,16,4,2,6,39,39,2,1,143,2,15,16,4,2,7,39,39, +2,1,143,2,15,16,4,2,8,39,39,2,1,143,2,15,16,4,2,9,39, +39,2,1,143,2,15,16,4,2,10,39,39,2,1,16,0,38,15,143,2,14, +2,11,18,143,16,2,143,10,16,3,9,2,11,2,13,143,11,16,3,9,9, +2,13,16,3,9,9,9,144,39,20,121,145,2,1,39,16,1,11,16,0,20, +27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9,11,11,11, +33,16,39,80,143,39,39,20,121,145,2,1,39,16,0,16,0,40,42,39,16, +0,39,16,0,39,11,11,11,16,0,16,0,16,0,39,39,40,12,11,11,16, +0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,0, +104,2,4,2,5,29,94,2,3,71,35,37,102,111,114,101,105,103,110,11,29, +94,2,3,70,35,37,117,110,115,97,102,101,11,29,94,2,3,71,35,37,102, +108,102,120,110,117,109,11,2,6,2,7,2,8,2,9,2,10,29,94,2,3, +69,35,37,112,108,97,99,101,11,29,94,2,3,71,35,37,102,117,116,117,114, +101,115,11,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 533); } diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index 4d4f541641..2db6ad4505 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -114,6 +114,7 @@ static Scheme_Object *local_lift_expr(int argc, Scheme_Object *argv[]); static Scheme_Object *local_lift_exprs(int argc, Scheme_Object *argv[]); static Scheme_Object *local_lift_context(int argc, Scheme_Object *argv[]); static Scheme_Object *local_lift_end_statement(int argc, Scheme_Object *argv[]); +static Scheme_Object *local_lift_module(int argc, Scheme_Object *argv[]); static Scheme_Object *local_lift_require(int argc, Scheme_Object *argv[]); static Scheme_Object *local_lift_provide(int argc, Scheme_Object *argv[]); static Scheme_Object *make_introducer(int argc, Scheme_Object *argv[]); @@ -804,6 +805,7 @@ static void make_kernel_env(void) GLOBAL_PRIM_W_ARITY("syntax-local-lift-values-expression", local_lift_exprs, 2, 2, env); GLOBAL_PRIM_W_ARITY("syntax-local-lift-context", local_lift_context, 0, 0, env); GLOBAL_PRIM_W_ARITY("syntax-local-lift-module-end-declaration", local_lift_end_statement, 1, 1, env); + GLOBAL_PRIM_W_ARITY("syntax-local-lift-module", local_lift_module, 1, 1, env); GLOBAL_PRIM_W_ARITY("syntax-local-lift-require", local_lift_require, 2, 2, env); GLOBAL_PRIM_W_ARITY("syntax-local-lift-provide", local_lift_provide, 1, 1, env); @@ -2772,6 +2774,25 @@ local_lift_end_statement(int argc, Scheme_Object *argv[]) return scheme_local_lift_end_statement(expr, local_scope, env); } +static Scheme_Object * +local_lift_module(int argc, Scheme_Object *argv[]) +{ + Scheme_Comp_Env *env; + Scheme_Object *local_scope, *expr; + + expr = argv[0]; + if (!SCHEME_STXP(expr)) + scheme_wrong_contract("syntax-local-lift-module", "syntax?", 0, argc, argv); + + env = scheme_current_thread->current_local_env; + local_scope = scheme_current_thread->current_local_scope; + + if (!env) + not_currently_transforming("syntax-local-lift-module"); + + return scheme_local_lift_module(expr, local_scope, env); +} + static Scheme_Object *local_lift_require(int argc, Scheme_Object *argv[]) { Scheme_Comp_Env *env; diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 4b95814f19..01cf3f8cee 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -4148,7 +4148,9 @@ static void *compile_k(void) before the rest. */ while (1) { scheme_frame_captures_lifts(cenv, scheme_make_lifted_defn, scheme_sys_wraps(cenv), - scheme_false, scheme_top_level_lifts_key(cenv), scheme_null, scheme_false); + scheme_false, scheme_top_level_lifts_key(cenv), scheme_null, scheme_false, + /* lifted modules like definitions: */ + scheme_true); form = scheme_check_immediate_macro(form, cenv, &rec, 0, &gval, @@ -4195,7 +4197,9 @@ static void *compile_k(void) while (1) { scheme_frame_captures_lifts(cenv, scheme_make_lifted_defn, scheme_sys_wraps(cenv), - scheme_false, scheme_top_level_lifts_key(cenv), scheme_null, scheme_false); + scheme_false, scheme_top_level_lifts_key(cenv), scheme_null, scheme_false, + /* lifted modules like definitions: */ + scheme_true); scheme_init_compile_recs(&rec, 0, &rec2, 1); @@ -4650,7 +4654,13 @@ static void *expand_k(void) data, scheme_false, catch_lifts_key, (!as_local && catch_lifts_key) ? scheme_null : NULL, - scheme_false); + scheme_false, + /* lifted modules like definitions: */ + ((env->flags & SCHEME_TOPLEVEL_FRAME) + ? scheme_true /* lifted `module` like definition */ + : ((env->flags & SCHEME_MODULE_FRAME) + ? scheme_void /* lifted `module[*]` like definition */ + : scheme_false))); } if (just_to_top) { @@ -5268,7 +5278,12 @@ do_local_expand(const char *name, int for_stx, int catch_lifts, int for_expr, in data, scheme_top_level_lifts_key(env), catch_lifts_key, NULL, - scheme_false); + scheme_false, + ((kind & SCHEME_TOPLEVEL_FRAME) + ? scheme_true /* lifted `module` like definition */ + : ((kind & SCHEME_MODULE_FRAME) + ? scheme_void /* lifted `module[*]` like definition */ + : scheme_false))); /* no lifted modules */ } memset(drec, 0, sizeof(drec)); diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index bf6cc7b660..e16754cbcf 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -8563,6 +8563,79 @@ static Scheme_Object *revert_use_site_scopes_via_context(Scheme_Object *o, Schem SCHEME_STX_REMOVE); } +static Scheme_Object *handle_submodule_form(const char *who, + Scheme_Object *e, + Scheme_Comp_Env *env, int phase, + Scheme_Object *rn_set, Scheme_Object *observer, + Module_Begin_Expand_State *bxs, + Scheme_Compile_Expand_Info *rec, int drec, + Scheme_Compile_Expand_Info *erec, int derec, + int *_kind) +{ + Scheme_Object *name = NULL, *fst, *p; + int is_star; + + fst = SCHEME_STX_CAR(e); + + is_star = scheme_stx_free_eq_x(scheme_modulestar_stx, fst, phase); + + e = revert_use_site_scopes_via_context(e, rn_set, phase); + + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); + if (is_star) { + SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE_STAR(observer); + } else { + SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE(observer); + } + + if (SCHEME_STX_PAIRP(e)) { + p = SCHEME_STX_CDR(e); + if (SCHEME_STX_PAIRP(p)) { + name = SCHEME_STX_CAR(p); + p = SCHEME_STX_CDR(p); + if (!SCHEME_STX_SYMBOLP(name) + || !SCHEME_STX_PAIRP(p)) { + name = NULL; + } + } + } + if (!name) { + scheme_wrong_syntax(who, NULL, e, NULL); + } + + if (!bxs->submodule_names) { + Scheme_Hash_Table *smn; + smn = scheme_make_hash_table(SCHEME_hash_ptr); + bxs->submodule_names = smn; + } + if (scheme_hash_get(bxs->submodule_names, SCHEME_STX_VAL(name))) { + scheme_wrong_syntax(who, name, fst, "duplicate submodule definition"); + } + scheme_hash_set(bxs->submodule_names, + SCHEME_STX_VAL(name), + is_star ? scheme_void : scheme_true); + + if (!is_star) { + p = expand_submodules(erec ? erec : rec, erec ? derec :drec, env, + scheme_make_pair(scheme_make_pair(e, scheme_make_integer(phase)), scheme_null), 0, + bxs, !!erec); + if (erec) + e = SCHEME_CAR(p); + else + e = NULL; + *_kind = DONE_MODFORM_KIND; + } else { + p = scheme_make_pair(scheme_make_pair(e, scheme_make_integer(phase)), + bxs->saved_submodules); + bxs->saved_submodules = p; + *_kind = MODULE_MODFORM_KIND; + } + + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer,e); + + return e; +} + static Scheme_Object *do_module_begin_k(void) { Scheme_Thread *p = scheme_current_thread; @@ -8784,7 +8857,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ ? scheme_frame_get_provide_lifts(xenv) : scheme_null); scheme_frame_captures_lifts(xenv, scheme_make_lifted_defn, scheme_sys_wraps(xenv), - p, lift_ctx, req_data, prev_p); + p, lift_ctx, req_data, prev_p, scheme_void); maybe_has_lifts = 1; { @@ -8981,7 +9054,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ 0); if (!for_stx) scheme_frame_captures_lifts(eenv, NULL, NULL, scheme_false, scheme_false, - req_data, scheme_false); + req_data, scheme_false, scheme_false); oenv = env; @@ -9220,63 +9293,14 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ || scheme_stx_free_eq_x(scheme_modulestar_stx, fst, phase)) { /************ module[*] *************/ /* check outer syntax & name, then expand pre-module or remember for post-module pass */ - Scheme_Object *name = NULL; - int is_star; - - is_star = scheme_stx_free_eq_x(scheme_modulestar_stx, fst, phase); - - e = revert_use_site_scopes_via_context(e, rn_set, phase); - - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); - if (is_star) { - SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE_STAR(observer); - } else { - SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE(observer); - } - - if (SCHEME_STX_PAIRP(e)) { - p = SCHEME_STX_CDR(e); - if (SCHEME_STX_PAIRP(p)) { - name = SCHEME_STX_CAR(p); - p = SCHEME_STX_CDR(p); - if (!SCHEME_STX_SYMBOLP(name) - || !SCHEME_STX_PAIRP(p)) { - name = NULL; - } - } - } - if (!name) { - scheme_wrong_syntax(who, NULL, e, NULL); - } - - if (!bxs->submodule_names) { - Scheme_Hash_Table *smn; - smn = scheme_make_hash_table(SCHEME_hash_ptr); - bxs->submodule_names = smn; - } - if (scheme_hash_get(bxs->submodule_names, SCHEME_STX_VAL(name))) { - scheme_wrong_syntax(who, name, fst, "duplicate submodule definition"); - } - scheme_hash_set(bxs->submodule_names, - SCHEME_STX_VAL(name), - is_star ? scheme_void : scheme_true); - - if (!is_star) { - p = expand_submodules(erec ? erec : rec, erec ? derec :drec, env, - scheme_make_pair(scheme_make_pair(e, scheme_make_integer(phase)), scheme_null), 0, - bxs, !!erec); - if (erec) - e = SCHEME_CAR(p); - else - e = NULL; - kind = DONE_MODFORM_KIND; - } else { - p = scheme_make_pair(scheme_make_pair(e, scheme_make_integer(phase)), - bxs->saved_submodules); - bxs->saved_submodules = p; - kind = MODULE_MODFORM_KIND; - } - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer,e); + int k; + e = handle_submodule_form(who, + e, env, phase, + rn_set, observer, + bxs, + rec, drec, erec, derec, + &k); + kind = k; } else { kind = EXPR_MODFORM_KIND; non_phaseless |= NON_PHASELESS_FORM; @@ -9400,7 +9424,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ ll = (maybe_has_lifts ? scheme_frame_get_provide_lifts(cenv) : scheme_null); - scheme_frame_captures_lifts(cenv, add_lifted_defn, lift_data, l, lift_ctx, req_data, ll); + scheme_frame_captures_lifts(cenv, add_lifted_defn, lift_data, l, lift_ctx, req_data, ll, scheme_void); maybe_has_lifts = 1; if (kind == DEFN_MODFORM_KIND) @@ -9436,6 +9460,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ p = SCHEME_CDR(p); } else { /* Lifts - insert them and try again */ + Scheme_Object *fst; *bxs->all_simple_bindings = 0; SCHEME_EXPAND_OBSERVE_MODULE_LIFT_LOOP(observer, scheme_copy_list(l)); if (erec) { @@ -9447,7 +9472,29 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ e = scheme_make_pair(e, scheme_make_integer(DONE_MODFORM_KIND)); /* don't re-compile/-expand */ SCHEME_CAR(p) = e; for (ll = l; SCHEME_PAIRP(ll); ll = SCHEME_CDR(ll)) { - e = scheme_make_pair(SCHEME_CAR(ll), scheme_make_integer(DEFN_MODFORM_KIND)); + e = SCHEME_CAR(ll); + if (SCHEME_STX_PAIRP(SCHEME_CAR(e))) + fst = SCHEME_STX_CAR(SCHEME_CAR(e)); + else + fst = NULL; + if (fst + && (scheme_stx_free_eq3(fst, scheme_module_stx, scheme_make_integer(phase), scheme_make_integer(0)) + || scheme_stx_free_eq3(fst, scheme_modulestar_stx, scheme_make_integer(phase), scheme_make_integer(0)))) { + /* a `module` or `module*` form; handle as in first pass */ + int k; + e = handle_submodule_form(who, + e, env, phase, + rn_set, observer, + bxs, + rec, drec, erec, derec, + &k); + if (e) + e = scheme_make_pair(e, scheme_make_integer(k)); + else + e = scheme_make_pair(scheme_void, DONE_MODFORM_KIND); + } else { + e = scheme_make_pair(e, scheme_make_integer(DEFN_MODFORM_KIND)); + } SCHEME_CAR(ll) = e; } p = scheme_append(l, p); diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 45e66df415..0e2a470120 100644 --- a/racket/src/racket/src/schminc.h +++ b/racket/src/racket/src/schminc.h @@ -14,7 +14,7 @@ #define USE_COMPILED_STARTUP 1 -#define EXPECTED_PRIM_COUNT 1133 +#define EXPECTED_PRIM_COUNT 1134 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index e4effeefaa..d477767b74 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2835,6 +2835,8 @@ Scheme_Object *scheme_do_local_lift_expr(const char *who, int stx_pos, Scheme_Object *scheme_local_lift_context(Scheme_Comp_Env *env); Scheme_Object *scheme_local_lift_end_statement(Scheme_Object *expr, Scheme_Object *local_scope, Scheme_Comp_Env *env); +Scheme_Object *scheme_local_lift_module(Scheme_Object *expr, Scheme_Object *local_scope, + Scheme_Comp_Env *env); Scheme_Object *scheme_local_lift_require(Scheme_Object *form, Scheme_Object *orig_form, intptr_t phase, Scheme_Object *local_scope, Scheme_Comp_Env *env); @@ -2890,10 +2892,12 @@ Scheme_Object *scheme_extract_foreign(Scheme_Object *o); typedef Scheme_Object *(*Scheme_Lift_Capture_Proc)(Scheme_Object *, Scheme_Object **, Scheme_Object *, Scheme_Comp_Env *); void scheme_frame_captures_lifts(Scheme_Comp_Env *env, Scheme_Lift_Capture_Proc cp, Scheme_Object *data, Scheme_Object *end_stmts, Scheme_Object *context_key, - Scheme_Object *require_lifts, Scheme_Object *provide_lifts); + Scheme_Object *require_lifts, Scheme_Object *provide_lifts, + Scheme_Object *module_lifts); void scheme_propagate_require_lift_capture(Scheme_Comp_Env *orig_env, Scheme_Comp_Env *env); Scheme_Object *scheme_frame_get_lifts(Scheme_Comp_Env *env); Scheme_Object *scheme_frame_get_end_statement_lifts(Scheme_Comp_Env *env); +Scheme_Object *scheme_frame_get_end_modules(Scheme_Comp_Env *env); Scheme_Object *scheme_frame_get_require_lifts(Scheme_Comp_Env *env); Scheme_Object *scheme_frame_get_provide_lifts(Scheme_Comp_Env *env); Scheme_Object *scheme_generate_lifts_key(void); diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 2dd3e70717..403bb94c3b 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.9" +#define MZSCHEME_VERSION "6.2.900.10" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 9 +#define MZSCHEME_VERSION_W 10 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 80aac79507d3e7b17e309773f26f15a1606f26bd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 14 Aug 2015 17:09:56 -0600 Subject: [PATCH 062/381] change `place` to create a submodule When `place` expands, the body of the `place` form is placed into a `(module* place-body- #f ....)` submodule. The `place` form previously placed its body in a lifted function, where the function's exported name was based on `(current-inexact-milliseconds)`. The generated submodules have deterministic names, so that compilation is deterministic, and submodule names don't collide (unlike exported function names) when multiple `place`-using module are imported into some other module. Also, using a submodule avoids the problem that the clock doesn't change fast enough on Windows. --- .../scribblings/reference/places.scrbl | 10 +++++++-- racket/collects/racket/place.rkt | 21 +++++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/places.scrbl b/pkgs/racket-doc/scribblings/reference/places.scrbl index 19d16a319a..15fbd3d22e 100644 --- a/pkgs/racket-doc/scribblings/reference/places.scrbl +++ b/pkgs/racket-doc/scribblings/reference/places.scrbl @@ -240,10 +240,16 @@ The @racket[dynamic-place*] binding is protected in the same way as expressions with @racket[id] bound to a place channel. The @racket[body]s close only over @racket[id] plus the top-level bindings of the enclosing module, because the - @racket[body]s are lifted to a function that is exported by - the module. The result of @racket[place] is a place descriptor, + @racket[body]s are lifted to a submodule. + The result of @racket[place] is a place descriptor, like the result of @racket[dynamic-place]. +The generated submodule has the name @racketidfont{place-body-@racket[_n]} +for an integer @racket[_n], and the submodule exports a @racket[main] +function that takes a place channel for the new place. The submodule +is not intended for use, however, except by the expansion of the +@racket[place] form. + The @racket[place] binding is protected in the same way as @racket[dynamic-place].} diff --git a/racket/collects/racket/place.rkt b/racket/collects/racket/place.rkt index cd3d8d9973..e62cb8e71b 100644 --- a/racket/collects/racket/place.rkt +++ b/racket/collects/racket/place.rkt @@ -179,6 +179,8 @@ [(symbol? name) (symbol->string name)] [(path? name) (path->string name)])])) +(define-for-syntax place-body-counter 0) + (define-for-syntax (place-form _in _out _err _start-place-func stx orig-stx) (syntax-case stx () [(who ch body1 body ...) @@ -191,20 +193,21 @@ (raise-syntax-error #f "can only be used in a module" stx)) (unless (identifier? #'ch) (raise-syntax-error #f "expected an identifier" stx #'ch)) - (define func-name-stx + (set! place-body-counter (add1 place-body-counter)) + (define module-name-stx (datum->syntax stx (string->symbol - (string-append "place/anon" - (modpath->string (current-module-declare-name)))))) + (format "place-body-~a" place-body-counter)))) (with-syntax ([internal-def-name - (syntax-local-lift-expression #'(lambda (ch) body1 body ...))] - [func-name (generate-temporary func-name-stx)] + (syntax-local-lift-module #`(module* #,module-name-stx #f + (provide main) + (define (main ch) + body1 body ...)))] [in _in] [out _out] [err _err] [start-place-func _start-place-func]) - (syntax-local-lift-provide #'(rename internal-def-name func-name)) - #'(place/proc (#%variable-reference) 'func-name 'who start-place-func in out err))))] + #`(place/proc (#%variable-reference) '#,module-name-stx 'who start-place-func in out err))))] [(_ ch) (raise-syntax-error #f "expected at least one body expression" orig-stx)])) @@ -222,7 +225,7 @@ [(pf #:err err ch body ...) (place-form #'#f #'#f #'err #'start-place* #'(pf ch body ...) stx)] [(pf ch body ...) (place-form #'#f #'#f #'#f #'start-place* #'(pf ch body ...) stx)])) -(define (place/proc vr func-name who start-place-func in out err) +(define (place/proc vr submod-name who start-place-func in out err) (define name (resolved-module-path-name (variable-reference->resolved-module-path @@ -230,7 +233,7 @@ (when (and (symbol? name) (not (module-predefined? `(quote ,name)))) (error who "the enclosing module's resolved name is not a path or predefined")) - (start-place-func who (if (symbol? name) `(quote ,name) name) func-name in out err)) + (start-place-func who `(submod ,(if (symbol? name) `(quote ,name) name) ,submod-name) 'main in out err)) (define-syntax (place/context stx) (syntax-parse stx From 1753335d345d85e15b6003be85bbc908e7f6b1a1 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Fri, 14 Aug 2015 00:09:53 -0300 Subject: [PATCH 063/381] Fix string-replace when the string is mutable The `from` string argument is converted to a regexp and cached. When `from` is a mutable string this can cause wrong results in the following calls to string-replace. So the string is first converted to an immutable string to be used as the key for the cache. --- .../racket-test-core/tests/racket/string.rktl | 7 +++++ racket/collects/racket/string.rkt | 29 +++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/string.rktl b/pkgs/racket-test-core/tests/racket/string.rktl index e429144c2d..cf0a959119 100644 --- a/pkgs/racket-test-core/tests/racket/string.rktl +++ b/pkgs/racket-test-core/tests/racket/string.rktl @@ -483,4 +483,11 @@ (test "foo\\1bar" string-replace "foo===bar" #rx"(=+)" "\\1") (test "foo\\1bar" string-replace "foo===bar" #px"={3}" "\\1")) +;test that mutable string are not cached incorrectly +(let ([str (string-copy "_1_")]) + (test "!!! _2_" string-replace "_1_ _2_" str "!!!") ;add str to the internal cache + (string-set! str 1 #\2) + (test "_1_ !!!" string-replace "_1_ _2_" str "!!!") ;verify that the new str is used +) + (report-errs) diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index 7df9f8e839..29e3e57367 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -100,17 +100,36 @@ (string-join (internal-split 'string-normalize-spaces str sep trim? +?) space)) -(define replace-cache (make-weak-hasheq)) + +;; Caches for string-replace: +;; A mutable string weakly holds a immutable copy until it is collected +;; or modified (and used as a argument of string-replace). +;; The immutable copy weakly holds the regexp that is used in string-replace. +;; Using string->immutable-string directly in string-replace is not a useful +;; because the immutable copy could be immediately collected. + +(define immutable-cache (make-weak-hasheq)) +(define (string->immutable-string/cache str) + (if (immutable? str) + str + (let ([old (hash-ref immutable-cache str #f)]) + (if (and old (string=? str old)) + old + (let ([new (string->immutable-string str)]) + (hash-set! immutable-cache str new) + new))))) + +(define replace-cache (make-weak-hash)) (define (string-replace str from to #:all? [all? #t]) (unless (string? str) (raise-argument-error 'string-replace "string?" str)) (unless (string? to) (raise-argument-error 'string-replace "string?" to)) + (unless (or (string? from) (regexp? from)) + (raise-argument-error 'string-replace "(or/c string? regexp?)" from)) (define from* (if (regexp? from) from - (hash-ref! replace-cache from - (λ() (if (string? from) - (regexp (regexp-quote from)) - (raise-argument-error 'string-replace "string?" from)))))) + (hash-ref! replace-cache (string->immutable-string/cache from) + (λ() (regexp (regexp-quote from)))))) (define to* (regexp-replace-quote to)) (if all? (regexp-replace* from* str to*) From be66fde64cfb476e4258bb3584f2bd8e651a5c01 Mon Sep 17 00:00:00 2001 From: Geoff Hill Date: Sat, 15 Aug 2015 00:41:46 -0700 Subject: [PATCH 064/381] write-xexpr: consistently use parameter port. --- racket/collects/xml/private/xexpr.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/xml/private/xexpr.rkt b/racket/collects/xml/private/xexpr.rkt index add87dd5f1..5dbad64766 100644 --- a/racket/collects/xml/private/xexpr.rkt +++ b/racket/collects/xml/private/xexpr.rkt @@ -131,7 +131,7 @@ (write-string/escape (cadr att) escape-attribute-table out) (write-string "\"" out)) (when insert-newlines? - (newline)) + (newline out)) ; Write end of opening tag (if (and (null? content) (case short From dfd2c6dc6896a87ca3bc26c807fac1481d4792fd Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sun, 16 Aug 2015 18:55:00 -0400 Subject: [PATCH 065/381] Hide output to work around racket/rackunit#5. --- pkgs/racket-test/tests/syntax/run.rkt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/syntax/run.rkt b/pkgs/racket-test/tests/syntax/run.rkt index 4fba39bf46..d3d0e2a422 100644 --- a/pkgs/racket-test/tests/syntax/run.rkt +++ b/pkgs/racket-test/tests/syntax/run.rkt @@ -1,6 +1,6 @@ #lang racket/base -(require rackunit rackunit/text-ui racket/runtime-path) +(require rackunit rackunit/text-ui racket/runtime-path racket/port) ;; Runs all the files in the tests subdirectory. ;; A test fails if it throws an exception. @@ -15,6 +15,8 @@ (test-suite (path->string t) (check-not-exn (lambda () - (dynamic-require (build-path tests-dir t) #f))))))) + (with-output-to-string + (lambda () + (dynamic-require (build-path tests-dir t) #f))))))))) (run-tests tests) From 5d9f63d800f9d32dbbba0c94101b82f73b442e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=B9=E5=9F=8E?= Date: Sat, 15 Aug 2015 17:23:52 +0800 Subject: [PATCH 066/381] Better description Better description about "binary-keep-files" --- pkgs/racket-doc/pkg/scribblings/strip.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/pkg/scribblings/strip.scrbl b/pkgs/racket-doc/pkg/scribblings/strip.scrbl index d35b3fcf09..29bcb8d1b2 100644 --- a/pkgs/racket-doc/pkg/scribblings/strip.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/strip.scrbl @@ -74,7 +74,7 @@ the following files and directories: Any of the above can be suppressed, however, by a @racket[source-keep-files] (for @tech{source package} and @tech{built package} bundling), @racket[binary-keep-files] (for @tech{binary -package}, @tech{binary library package} @tech{built package} bundling), +package}, @tech{binary library package} and @tech{built package} bundling), or @racket[binary-lib-keep-files] (for @tech{binary library package} bundling) definition in an @filepath{info.rkt} in the package or any subdirectory. A @racket[source-keep-files], @racket[binary-keep-files], or @racket[binary-lib-keep-files] definition From a3e359d9e167365887b0a9b4948c7fe859869021 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Aug 2015 07:20:46 -0600 Subject: [PATCH 067/381] refine use of "Unix" in the installation instructions Based on a suggestion from enedil , avoid suggesting that OS X is not Unix or that Linux is truly Unix. --- INSTALL.txt | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/INSTALL.txt b/INSTALL.txt index 0569ed2ad9..202705e4ba 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,8 +1,8 @@ Build Options ============= -For Unix platforms, instead of using this source repository, consider -getting source for the current Racket release from +Instead of using this source repository, consider getting source for +the current Racket release from http://download.racket-lang.org/ @@ -16,7 +16,9 @@ documentation are pre-built. In contrast to this repository, release and snapshot source distributions will work in the + configure --prefix=... && make && make install + way that you probably expect. @@ -31,7 +33,7 @@ If you stick with this repository, then you have several options: Instructions: In-place Build" below. * Unix-style install --- installs to a given destination directory - (Unix and Mac OS X, only), leaving no reference to the source + (on platforms other Windows), leaving no reference to the source directory. This is the most natural mode for installing once from the source repository. See "Quick Instructions: Unix-style Install" below. @@ -51,8 +53,8 @@ If you stick with this repository, then you have several options: Quick Instructions: In-place Build ================================== -On Unix, `make' (or `make in-place') creates a build in the "racket" -directory. +On Unix (including Linux) and Mac OS X, `make' (or `make in-place') +creates a build in the "racket" directory. On Windows with Microsoft Visual Studio (any version between 2008/9.0 and 2013/12.0), `nmake win32-in-place' creates a build in the "racket" @@ -74,10 +76,10 @@ See "More Instructions: Building Racket" below for more information. Quick Instructions: Unix-style Install ====================================== -On Unix, `make unix-style PREFIX=' builds and installs into -"" (which must be an absolute path) with binaries in "/bin", -packages in "/share/racket/pkgs", documentation in -"/share/racket/doc", etc. +On Unix (including Linux), `make unix-style PREFIX=' builds and +installs into "" (which must be an absolute path) with binaries +in "/bin", packages in "/share/racket/pkgs", documentation +in "/share/racket/doc", etc. On Mac OS X, `make unix-style PREFIX=' builds and installs into "" (whichmust be an absolute path) with binaries in "/bin", @@ -305,8 +307,8 @@ where defaults to "racket" (but can be set via normalizing the Windows results to "i386-win32" and "x86_63-win32", - is omitted unless a `#:dist-suffix' string is specified for the client in the site configuration, and is -platform-specific: ".sh" for Unix, ".dmg" or ".pkg" for Mac OS X, and -".exe" for Windows. +platform-specific: ".sh" for Unix (including Linux), ".dmg" or ".pkg" +for Mac OS X, and ".exe" for Windows. Generating Installer Web Sites ------------------------------ @@ -475,8 +477,8 @@ In more detail: To change the base name of the installer file, provide `DIST_BASE' to `make'. The default is "racket". - To change the directory name for Unix installation, provide - `DIST_DIR' to `make'. The default is "racket". + To change the directory name for installation on Unix (including + Linux), provide `DIST_DIR' to `make'. The default is "racket". To add an extra piece to the installer's name, such as an identifier for a variant of Linux, provide `DIST_SUFFIX' to From fea2b1ce5e964aafbb72a8e6ec2a6be8441e5e01 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Aug 2015 08:32:12 -0600 Subject: [PATCH 068/381] repairs for MinGW build Fix compiler warnings and installation bugs related to the ".exe" extension. --- racket/collects/compiler/private/xform.rkt | 9 +++++---- racket/src/gracket/Makefile.in | 4 ++-- racket/src/gracket/grmain.c | 6 ++++-- racket/src/racket/Makefile.in | 4 ++-- racket/src/racket/dynsrc/Makefile.in | 8 ++++---- racket/src/racket/dynsrc/start.c | 4 ++-- racket/src/racket/include/scheme.h | 4 ++-- racket/src/racket/src/file.c | 10 +++++----- racket/src/racket/src/mzrt.c | 4 ++-- 9 files changed, 28 insertions(+), 25 deletions(-) diff --git a/racket/collects/compiler/private/xform.rkt b/racket/collects/compiler/private/xform.rkt index 63e8dd4c2a..534fabb736 100644 --- a/racket/collects/compiler/private/xform.rkt +++ b/racket/collects/compiler/private/xform.rkt @@ -3997,8 +3997,6 @@ ;; Not a decl (values (reverse decls) el)))))) - (define braces-then-semi '(typedef struct union enum __extension__)) - (define (get-one e comma-sep?) (let loop ([e e][result null][first #f][second #f]) (cond @@ -4018,7 +4016,7 @@ [(and (eq? '|,| (tok-n (car e))) comma-sep?) (values (reverse (cons (car e) result)) (cdr e))] [(and (braces? (car e)) - (not (memq first '(typedef enum __extension__))) + (not (memq first '(typedef enum))) (or (not (memq first '(static extern const struct union))) (equal? second "C") ; => extern "C" ... (equal? second "C++") ; => extern "C++" ... @@ -4030,7 +4028,10 @@ (values (reverse (cons (car e) result)) rest) (values (reverse (list* (car rest) (car e) result)) (cdr rest))))] [else (loop (cdr e) (cons (car e) result) - (or first (tok-n (car e))) + (or first (let ([s (tok-n (car e))]) + (if (memq s '(__extension__)) + #f ; skip over annotation when deciding shape + s))) (or second (and first (tok-n (car e)))))]))) (define (foldl-statement e comma-sep? f a-init) diff --git a/racket/src/gracket/Makefile.in b/racket/src/gracket/Makefile.in index e1ff600bea..c5330870ec 100644 --- a/racket/src/gracket/Makefile.in +++ b/racket/src/gracket/Makefile.in @@ -204,7 +204,7 @@ install-lib-cgc-wx_xt: install-wx_xt-cgc: $(MAKE) @MRLIBINSTALL@-cgc-wx_xt - cd ..; $(ICP) gracket/gracket@CGC@ "$(DESTDIR)$(libpltdir)/gracket@CGC_INSTALLED@" + cd ..; $(ICP) gracket/gracket@CGC@ "$(DESTDIR)$(libpltdir)/gracket@CGC_INSTALLED@@EXE_SUFFIX@" cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/gracket@CGC_INSTALLED@@EXE_SUFFIX@" @RUN_RACKET_CGC@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/gracket@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ @@ -219,7 +219,7 @@ install-lib-3m-wx_xt: install-wx_xt-3m: $(MAKE) @MRLIBINSTALL@-3m-wx_xt - cd ..; $(ICP) gracket/gracket@MMM@ "$(DESTDIR)$(libpltdir)/gracket@MMM_INSTALLED@" + cd ..; $(ICP) gracket/gracket@MMM@ "$(DESTDIR)$(libpltdir)/gracket@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/gracket@MMM_INSTALLED@@EXE_SUFFIX@" @RUN_RACKET_MMM@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/gracket@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ diff --git a/racket/src/gracket/grmain.c b/racket/src/gracket/grmain.c index 9debfa986b..b47e7e9e6e 100644 --- a/racket/src/gracket/grmain.c +++ b/racket/src/gracket/grmain.c @@ -52,7 +52,9 @@ static void pre_filter_cmdline_arguments(int *argc, char ***argv); #if WIN32 # define DLL_RELATIVE_PATH L"." -# define INITIAL_COLLECTS_DIRECTORY "../collects" +# ifndef INITIAL_COLLECTS_DIRECTORY +# define INITIAL_COLLECTS_DIRECTORY "../collects" +# endif #endif #ifndef INITIAL_CONFIG_DIRECTORY @@ -113,7 +115,7 @@ static void init_console_in() if (!console_in) { console_in = GetStdHandle(STD_INPUT_HANDLE); MZ_REGISTER_STATIC(console_inport); - console_inport = scheme_make_fd_input_port((int)console_in, scheme_intern_symbol("stdin"), 0, 0); + console_inport = scheme_make_fd_input_port((intptr_t)console_in, scheme_intern_symbol("stdin"), 0, 0); } } diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index b547c5e3c4..7e1ad7ad1f 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -405,14 +405,14 @@ mingw-install: mingw-install-cgc: cd ..; $(ICP) racket/lib/libmzgcxxxxxxx.dll "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" cd ..; $(ICP) racket/lib/libracketxxxxxxx.dll "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll" - cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@" + cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" @RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ mingw-install-cgc-final: $(NOOP) mingw-install-3m: - cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@" + cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(ICP) racket/lib/libracket3mxxxxxxx.dll "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll" @RUN_RACKET_MMM@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ diff --git a/racket/src/racket/dynsrc/Makefile.in b/racket/src/racket/dynsrc/Makefile.in index 8dc2f016eb..5c88395a92 100644 --- a/racket/src/racket/dynsrc/Makefile.in +++ b/racket/src/racket/dynsrc/Makefile.in @@ -25,7 +25,7 @@ ALL_CFLAGS = $(CFLAGS) $(CPPFLAGS) -I$(builddir)/.. -I$(srcdir)/../include -I$(s dynlib: $(MAKE) ../mzdyn.o - $(MAKE) ../starter + $(MAKE) ../starter@EXE_SUFFIX@ dynlib3m: $(MAKE) ../mzdyn3m.o @@ -53,12 +53,12 @@ dynexmpl.o: $(srcdir)/dynexmpl.c $(HEADERS) $(PLAIN_CC) $(ALL_CFLAGS) -c $(srcdir)/dynexmpl.c -o dynexmpl.o ../starter@NOT_MINGW@@EXE_SUFFIX@: $(srcdir)/ustart.c - $(PLAIN_CC) $(ALL_CFLAGS) -o ../starter $(srcdir)/ustart.c + $(PLAIN_CC) $(ALL_CFLAGS) -o ../starter@EXE_SUFFIX@ $(srcdir)/ustart.c ../starter@MINGW@@EXE_SUFFIX@: $(srcdir)/start.c ../mrstarter@EXE_SUFFIX@ sres.o - $(PLAIN_CC) $(ALL_CFLAGS) -o ../starter $(srcdir)/start.c sres.o + $(PLAIN_CC) $(ALL_CFLAGS) -o ../starter@EXE_SUFFIX@ $(srcdir)/start.c sres.o ../mrstarter@EXE_SUFFIX@: sres.o - $(PLAIN_CC) $(ALL_CFLAGS) -mwindows -DMRSTART -o ../mrstarter $(srcdir)/start.c sres.o + $(PLAIN_CC) $(ALL_CFLAGS) -mwindows -DMRSTART -o ../mrstarter@EXE_SUFFIX@ $(srcdir)/start.c sres.o sres.o: @WINDRES@ -i $(srcdir)/../../worksp/starters/start.rc -o sres.o diff --git a/racket/src/racket/dynsrc/start.c b/racket/src/racket/dynsrc/start.c index 2111910152..7e00019e64 100644 --- a/racket/src/racket/dynsrc/start.c +++ b/racket/src/racket/dynsrc/start.c @@ -320,7 +320,7 @@ int wmain(int argc_in, wchar_t **argv_in) if (_wstat(go, &st)) { #ifdef USE_WINMAIN wchar_t errbuff[MAXCOMMANDLEN * 2]; - swprintf(errbuff,L"Can't find %s",go); + swprintf(errbuff,sizeof(errbuff),L"Can't find %s",go); MessageBoxW(NULL,errbuff,L"Error",MB_OK); #else char errbuff[MAXCOMMANDLEN * 2]; @@ -367,7 +367,7 @@ int wmain(int argc_in, wchar_t **argv_in) if (cl_len > MAXCOMMANDLEN) { #ifdef MRSTART wchar_t errbuff[MAXCOMMANDLEN * 2]; - swprintf(errbuff,L"Command line of %d characters exceeds %d characters: %.1024s", + swprintf(errbuff,sizeof(errbuff),L"Command line of %d characters exceeds %d characters: %.1024s", cl_len, MAXCOMMANDLEN,command_line); MessageBoxW(NULL,errbuff,L"Error",MB_OK); #else diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 113ca373ae..91a5d30b88 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1906,8 +1906,8 @@ MZ_EXTERN void scheme_register_embedded_load(intptr_t len, const char *s); typedef void (*Scheme_Exit_Proc)(int v); MZ_EXTERN Scheme_Exit_Proc scheme_exit; MZ_EXTERN void scheme_set_exit(Scheme_Exit_Proc p); -typedef void (*Scheme_At_Exit_Callback_Proc)(); -typedef void (*Scheme_At_Exit_Proc)(Scheme_At_Exit_Callback_Proc); +typedef void (*Scheme_At_Exit_Callback_Proc)(void); +typedef int (*Scheme_At_Exit_Proc)(Scheme_At_Exit_Callback_Proc); MZ_EXTERN void scheme_set_atexit(Scheme_At_Exit_Proc p); typedef void (*scheme_console_printf_t)(char *str, ...); MZ_EXTERN scheme_console_printf_t scheme_console_printf; diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index 1209ef82f3..fdfdbe689e 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -2411,9 +2411,9 @@ Scheme_Object *combine_link_path(char *copy, int len, char *clink, int clen, # define MZ_UNC_WRITE 0x2 # define MZ_UNC_EXEC 0x4 -static int UNC_stat(char *dirname, int len, int *flags, int *isdir, int *islink, +static int UNC_stat(const char *dirname, int len, int *flags, int *isdir, int *islink, Scheme_Object **date, mzlonglong *filesize, - char **resolved_path, int set_flags) + const char **resolved_path, int set_flags) /* dirname must be absolute */ { /* Note: stat() doesn't work with UNC "drive" names or \\?\ paths. @@ -4179,7 +4179,7 @@ static char *filename_for_error(Scheme_Object *p) } #ifdef DOS_FILE_SYSTEM -static int enable_write_permission(char *fn) +static int enable_write_permission(const char *fn) { int len; int flags; @@ -5407,10 +5407,10 @@ static Scheme_Object *do_directory_list(int break_ok, int argc, Scheme_Object *a err_val = GetLastError(); if ((err_val == ERROR_DIRECTORY) && CreateSymbolicLinkProc) { /* check for symbolic link */ - char *resolved; + const char *resolved; if (UNC_stat(filename, strlen(filename), NULL, NULL, NULL, NULL, NULL, &resolved, -1)) { if (resolved) { - filename = resolved; + filename = (char *)resolved; goto retry; } } diff --git a/racket/src/racket/src/mzrt.c b/racket/src/racket/src/mzrt.c index 4075c7e44a..269abff799 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -178,9 +178,9 @@ void *mzrt_thread_stub(void *data){ } #ifdef WIN32 -DWORD WINAPI mzrt_win_thread_stub(void *data) +uintptr_t WINAPI mzrt_win_thread_stub(void *data) { - return (DWORD)mzrt_thread_stub(data); + return (uintptr_t)mzrt_thread_stub(data); } #endif From 693cdc673d88e1f93bb4e7a596f49474c07a011b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Aug 2015 09:39:11 -0600 Subject: [PATCH 069/381] GC: use ofm_malloc() and ofm_free() for admin allocation Using ofm_....() makes it easier to check that memory allocated for GC administrtation is itself reclaimed. --- racket/src/racket/gc2/alloc_cache.c | 2 +- racket/src/racket/gc2/block_cache.c | 4 +- racket/src/racket/gc2/mem_account.c | 10 ++-- racket/src/racket/gc2/newgc.c | 87 +++++++++++++++++++---------- racket/src/racket/src/mzrt.c | 4 +- 5 files changed, 66 insertions(+), 41 deletions(-) diff --git a/racket/src/racket/gc2/alloc_cache.c b/racket/src/racket/gc2/alloc_cache.c index a195205597..711f0db621 100644 --- a/racket/src/racket/gc2/alloc_cache.c +++ b/racket/src/racket/gc2/alloc_cache.c @@ -36,7 +36,7 @@ static intptr_t alloc_cache_free_all_pages(AllocCacheBlock *blockfree); static intptr_t alloc_cache_free(AllocCacheBlock *ac) { if (ac) { intptr_t s = alloc_cache_free_all_pages(ac); - free(ac); + ofm_free(ac, sizeof(AllocCacheBlock) * BLOCKFREE_CACHE_SIZE); return s; } return 0; diff --git a/racket/src/racket/gc2/block_cache.c b/racket/src/racket/gc2/block_cache.c index fe2bf7558b..9764ce79f2 100644 --- a/racket/src/racket/gc2/block_cache.c +++ b/racket/src/racket/gc2/block_cache.c @@ -80,7 +80,7 @@ static BlockCache* block_cache_create(MMU *mmu) { static ssize_t block_cache_free(BlockCache* bc) { ssize_t acf = alloc_cache_free(bc->bigBlockCache); page_range_free(bc->page_range); - free(bc); + ofm_free(bc, sizeof(BlockCache)); return acf; } @@ -220,7 +220,7 @@ static ssize_t bc_free_std_block(block_desc *b) { gclist_del(&b->gclist); os_free_pages(b->block, b->size); size_diff -= b->size; - free(b); + ofm_free(b, sizeof(block_desc)); return size_diff; } diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 12d7dfa0dc..1f1565a2a7 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -97,7 +97,7 @@ inline static void clean_up_thread_list(NewGC *gc) if(prev) prev->next = next; if(!prev) gc->thread_infos = next; - free(work); + ofm_free(work, sizeof(GC_Thread_Info)); work = next; } } @@ -175,7 +175,7 @@ void BTC_register_root_custodian(void *_c) if (gc->owner_table) { /* Reset */ - free(gc->owner_table); + ofm_free(gc->owner_table, sizeof(OTEntry*) * gc->owner_table_size); gc->owner_table = NULL; gc->owner_table_size = 0; } @@ -214,7 +214,7 @@ inline static void free_owner_set(NewGC *gc, int set) { OTEntry **owner_table = gc->owner_table; if(owner_table[set]) { - free(owner_table[set]); + ofm_free(owner_table[set], sizeof(OTEntry)); } owner_table[set] = NULL; } @@ -558,7 +558,7 @@ inline static void clean_up_account_hooks(NewGC *gc) if(prev) prev->next = next; if(!prev) gc->hooks = next; - free(work); + ofm_free(work, sizeof(AccountHook)); work = next; } } @@ -615,7 +615,7 @@ inline static void BTC_run_account_hooks(NewGC *gc) if(prev) prev->next = next; if(!prev) gc->hooks = next; scheme_schedule_custodian_close(work->c2); - free(work); + ofm_free(work, sizeof(AccountHook)); work = next; } else { prev = work; diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 9c381792a7..8d43b52140 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -322,6 +322,11 @@ void GC_set_post_propagate_hook(GC_Post_Propagate_Hook_Proc func) { static void garbage_collect(NewGC*, int, int, int, Log_Master_Info*); static void collect_now(NewGC*, int, int); +#define TRACK_OFM_SIZE 0 +#if TRACK_OFM_SIZE +static int total_ofm_size; +#endif + static void out_of_memory() { if (GC_report_out_of_memory) @@ -337,6 +342,9 @@ inline static void out_of_memory_gc(NewGC* gc) { static void *ofm_malloc(size_t size) { void *ptr = malloc(size); if (!ptr) out_of_memory(); +#if TRACK_OFM_SIZE + total_ofm_size += size; +#endif return ptr; } @@ -347,6 +355,13 @@ static void *ofm_malloc_zero(size_t size) { return ptr; } +static void ofm_free(void *p, size_t size) { +#if TRACK_OFM_SIZE + total_ofm_size -= size; +#endif + free(p); +} + inline static size_t size_to_apage_count(size_t len) { return (len / APAGE_SIZE) + (((len % APAGE_SIZE) == 0) ? 0 : 1); } @@ -565,15 +580,15 @@ inline static void free_page_maps(PageMap page_maps1) { for (j=0; jsaved_alloc_page_ptr ; GC_gen0_alloc_page_end = a->saved_alloc_page_end ; - free(a); + ofm_free(a, sizeof(Allocator)); gc->saved_allocator = NULL; gc->in_unsafe_allocation_mode = 0; @@ -1797,7 +1812,7 @@ void GC_adopt_message_allocator(void *param) { msgm->pages->prev = gen0end; } } - free(msgm); + ofm_free(msgm, sizeof(MsgMemory)); /* Adopted enough to trigger a GC? */ gc_if_needed_account_alloc_size(gc, 0); @@ -1836,7 +1851,7 @@ void GC_dispose_short_message_allocator(void *param) { free_orphaned_page(gc, msgm->pages); } - free(msgm); + ofm_free(msgm, sizeof(MsgMemory)); } void GC_destroy_orphan_msg_memory(void *param) { @@ -1869,7 +1884,7 @@ void GC_destroy_orphan_msg_memory(void *param) { } } - free(msgm); + ofm_free(msgm, sizeof(MsgMemory)); } @@ -2614,7 +2629,7 @@ inline static void clear_stack_pages(NewGC *gc) if (!keep) gc->mark_stack->next = NULL; } else - free(gc->mark_stack); + ofm_free(gc->mark_stack, STACK_PART_SIZE); } gc->mark_stack = base; gc->mark_stack->top = MARK_STACK_START(gc->mark_stack); @@ -2631,7 +2646,7 @@ inline static void free_all_stack_pages(NewGC *gc) /* then go through and clear them out */ for(; gc->mark_stack; gc->mark_stack = temp) { temp = gc->mark_stack->next; - free(gc->mark_stack); + ofm_free(gc->mark_stack, STACK_PART_SIZE); } } } @@ -2797,7 +2812,7 @@ static void NewGCMasterInfo_initialize() { MASTERGCINFO->size = 32; MASTERGCINFO->alive = 0; MASTERGCINFO->ready = 0; - MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); + MASTERGCINFO->signal_fds = (void **)ofm_malloc(sizeof(void*) * MASTERGCINFO->size); for (i=0; i < 32; i++ ) { MASTERGCINFO->signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE; } @@ -2810,8 +2825,8 @@ static void NewGCMasterInfo_initialize() { /* Not yet used: */ static void NewGCMasterInfo_cleanup() { mzrt_rwlock_destroy(MASTERGCINFO->cangc); - free(MASTERGCINFO->signal_fds); - free(MASTERGCINFO); + ofm_free(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); + ofm_free(MASTERGCINFO, sizeof(NewGCMasterInfo)); MASTERGCINFO = NULL; } #endif @@ -2960,23 +2975,33 @@ static void wait_while_master_in_progress(NewGC *gc, Log_Master_Info *lmi) { /* MUST CALL WITH cangc lock */ static intptr_t NewGCMasterInfo_find_free_id() { + int i, size; + GC_ASSERT(MASTERGCINFO->alive <= MASTERGCINFO->size); if ((MASTERGCINFO->alive + 1) == MASTERGCINFO->size) { - MASTERGCINFO->size++; + void **new_signal_fds; + + size = MASTERGCINFO->size * 2; MASTERGCINFO->alive++; - MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); - return MASTERGCINFO->size - 1; + new_signal_fds = ofm_malloc(sizeof(void*) * size); + memcpy(new_signal_fds, MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); + + for (i = MASTERGCINFO->size; i < size; i++ ) { + new_signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE; + } + + MASTERGCINFO->signal_fds = new_signal_fds; + MASTERGCINFO->size = size; } - else { - int i; - int size = MASTERGCINFO->size; - for (i = 0; i < size; i++) { - if (MASTERGCINFO->signal_fds[i] == (void*) REAPED_SLOT_AVAILABLE) { - MASTERGCINFO->alive++; - return i; - } + + size = MASTERGCINFO->size; + for (i = 0; i < size; i++) { + if (MASTERGCINFO->signal_fds[i] == (void*) REAPED_SLOT_AVAILABLE) { + MASTERGCINFO->alive++; + return i; } } + printf("Error in MASTERGCINFO table\n"); abort(); return 0; @@ -5357,7 +5382,7 @@ static void free_child_gc(void) mmu_flush_freed_pages(gc->mmu); mmu_free(gc->mmu); - free(gc); + ofm_free(gc, sizeof(NewGC)); } #endif @@ -5388,12 +5413,12 @@ void GC_free_all(void) } } - free(gc->mark_table); - free(gc->fixup_table); + ofm_free(gc->mark_table, NUMBER_OF_TAGS * sizeof (Mark2_Proc)); + ofm_free(gc->fixup_table, NUMBER_OF_TAGS * sizeof (Fixup2_Proc)); free_page_maps(gc->page_maps); free_all_stack_pages(gc); mmu_flush_freed_pages(gc->mmu); mmu_free(gc->mmu); - free(gc); + ofm_free(gc, sizeof(NewGC)); } diff --git a/racket/src/racket/src/mzrt.c b/racket/src/racket/src/mzrt.c index 269abff799..4075c7e44a 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -178,9 +178,9 @@ void *mzrt_thread_stub(void *data){ } #ifdef WIN32 -uintptr_t WINAPI mzrt_win_thread_stub(void *data) +DWORD WINAPI mzrt_win_thread_stub(void *data) { - return (uintptr_t)mzrt_thread_stub(data); + return (DWORD)mzrt_thread_stub(data); } #endif From 641c56b6e95b57881b6fef846fb758ed5cd6e5a8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Aug 2015 09:46:07 -0600 Subject: [PATCH 070/381] repair leak in managing OS-level locks --- racket/src/racket/src/mzrt.c | 46 ++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/racket/src/racket/src/mzrt.c b/racket/src/racket/src/mzrt.c index 4075c7e44a..0765aa89d6 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -468,12 +468,15 @@ int mzrt_rwlock_unlock(mzrt_rwlock *lock) { } int mzrt_rwlock_destroy(mzrt_rwlock *lock) { - pthread_mutex_destroy(&lock->m); - pthread_cond_destroy(&lock->cr); - pthread_cond_destroy(&lock->cw); - free(lock); + int r = 0; - return 0; + r |= pthread_mutex_destroy(&lock->m); + r |= pthread_cond_destroy(&lock->cr); + r |= pthread_cond_destroy(&lock->cw); + + if (!r) free(lock); + + return r; } # endif @@ -500,7 +503,10 @@ int mzrt_mutex_unlock(mzrt_mutex *mutex) { } int mzrt_mutex_destroy(mzrt_mutex *mutex) { - return pthread_mutex_destroy(&mutex->mutex); + int r; + r = pthread_mutex_destroy(&mutex->mutex); + if (!r) free(mutex); + return r; } struct mzrt_cond { @@ -532,7 +538,10 @@ int mzrt_cond_broadcast(mzrt_cond *cond) { } int mzrt_cond_destroy(mzrt_cond *cond) { - return pthread_cond_destroy(&cond->cond); + int r; + r = pthread_cond_destroy(&cond->cond); + if (!r) free(cond); + return r; } struct mzrt_sema { @@ -588,11 +597,14 @@ int mzrt_sema_post(mzrt_sema *s) int mzrt_sema_destroy(mzrt_sema *s) { - pthread_mutex_destroy(&s->m); - pthread_cond_destroy(&s->c); - free(s); + int r = 0; - return 0; + r |= pthread_mutex_destroy(&s->m); + r |= pthread_cond_destroy(&s->c); + + if (!r) free(s); + + return r; } #endif @@ -697,7 +709,8 @@ int mzrt_rwlock_destroy(mzrt_rwlock *lock) { int rc = 1; rc &= CloseHandle(lock->readEvent); rc &= CloseHandle(lock->writeMutex); - return rc; + if (rc) free(lock); + return !rc; } struct mzrt_mutex { @@ -729,6 +742,7 @@ int mzrt_mutex_unlock(mzrt_mutex *mutex) { int mzrt_mutex_destroy(mzrt_mutex *mutex) { DeleteCriticalSection(&mutex->critical_section); + free(mutex); return 0; } @@ -791,10 +805,12 @@ int mzrt_sema_post(mzrt_sema *s) int mzrt_sema_destroy(mzrt_sema *s) { - CloseHandle(s->ws); - free(s); + int r; - return 0; + r = CloseHandle(s->ws); + if (r) free(s); + + return !r; } #endif From 1b493f21467dcfe1609f013847f1b4077b59c5bb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Aug 2015 10:16:02 -0600 Subject: [PATCH 071/381] fix MzCOM's atexit replacement --- racket/src/mzcom/mzobj.cxx | 3 +- .../worksp/mzcom/MzCOM.tmp_Release_x64.vcproj | 99 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj diff --git a/racket/src/mzcom/mzobj.cxx b/racket/src/mzcom/mzobj.cxx index 96d7bb45b8..e5df4c4487 100644 --- a/racket/src/mzcom/mzobj.cxx +++ b/racket/src/mzcom/mzobj.cxx @@ -302,9 +302,10 @@ static int do_evalLoop(Scheme_Env *env, int argc, char **_args) return 0; } -static void record_at_exit(Scheme_At_Exit_Callback_Proc p) XFORM_SKIP_PROC +static int record_at_exit(Scheme_At_Exit_Callback_Proc p) XFORM_SKIP_PROC { at_exit_callback = p; + return 0; } static __declspec(thread) void *tls_space; diff --git a/racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj b/racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj new file mode 100644 index 0000000000..b3bb7dab4c --- /dev/null +++ b/racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 629697d14a375d34b808be5cbf8dd4c6b687b3f2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Aug 2015 12:36:51 -0600 Subject: [PATCH 072/381] remove accidentally added file --- .../worksp/mzcom/MzCOM.tmp_Release_x64.vcproj | 99 ------------------- 1 file changed, 99 deletions(-) delete mode 100644 racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj diff --git a/racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj b/racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj deleted file mode 100644 index b3bb7dab4c..0000000000 --- a/racket/src/worksp/mzcom/MzCOM.tmp_Release_x64.vcproj +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 1079b2b790351ae03d50f8710525dbaa0af911c3 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 17 Aug 2015 16:54:29 -0500 Subject: [PATCH 073/381] Move unstable/socket to its own package. --- racket/collects/unstable/socket.rkt | 172 ---------------------------- 1 file changed, 172 deletions(-) delete mode 100644 racket/collects/unstable/socket.rkt diff --git a/racket/collects/unstable/socket.rkt b/racket/collects/unstable/socket.rkt deleted file mode 100644 index 0b9b7ff380..0000000000 --- a/racket/collects/unstable/socket.rkt +++ /dev/null @@ -1,172 +0,0 @@ -#lang racket/base - -;; Support for connecting to UNIX domain sockets. - -#| -References: -linux (64): - Linux Standard Base Core Specification 4.1 -macosx (64): - /usr/include/i386/_types.h: __darwin_socklen_t - /usr/include/sys/socket.h: AF_UNIX - /usr/include/sys/un.h: struct sockaddr_un -|# - -(require racket/contract - (rename-in ffi/unsafe (-> -->)) - ffi/unsafe/define - ffi/file - unstable/error) - -(provide - (contract-out - [unix-socket-available? - boolean?] - [unix-socket-connect - (-> unix-socket-path? (values input-port? output-port?))] - [unix-socket-path? - (-> any/c boolean?)])) - - -;; Data structures and error handling code differs between the platforms. -(define platform - (cond - [(eq? (system-type 'os) 'macosx) - 'macosx] - [(regexp-match? #rx"^Linux" (system-type 'machine)) - 'linux] - [else - #f])) - - -(define unix-socket-available? - (and platform #t)) - - -(define AF-UNIX 1) -(define SOCK-STREAM 1) - -(define UNIX-PATH-MAX - (case platform - [(linux) 108] - [else 104])) - -(define _socklen_t - (case platform - [(linux) _uint] - [else _uint32])) - -(define-cstruct _linux_sockaddr_un - ([sun_family _ushort] - [sun_path (make-array-type _byte UNIX-PATH-MAX)])) - -(define-cstruct _macosx_sockaddr_un - ([sun_len _ubyte] - [sun_family _ubyte] - [sun_path (make-array-type _byte UNIX-PATH-MAX)])) - -(define _sockaddr_un-pointer - (case platform - [(linux) _linux_sockaddr_un-pointer] - [(macosx) _macosx_sockaddr_un-pointer] - [else _pointer])) - - -(define-ffi-definer define-libc (ffi-lib #f) - #:default-make-fail make-not-available) - -(define-libc socket - (_fun #:save-errno 'posix - _int _int _int --> _int)) - -(define-libc connect - (_fun #:save-errno 'posix - _int _sockaddr_un-pointer _int --> _int)) - -(define-libc close - (_fun #:save-errno 'posix - _int --> _int)) - -(define-libc scheme_make_fd_output_port - (_fun _int _racket _bool _bool _bool --> _racket)) - -(define strerror-name - (case platform - [(linux) "__xpg_strerror_r"] - [else "strerror_r"])) - -(define strerror_r - (get-ffi-obj strerror-name #f - (_fun (errno) :: - (errno : _int) - (buf : _bytes = (make-bytes 1000)) - (buf-len : _size = (bytes-length buf)) - --> _void - --> (cast buf _bytes _string/locale)) - (lambda () - (lambda (errno) #f)))) - - -(define (unix-socket-path? v) - (and (unix-socket-path->bytes v) #t)) - -(define (unix-socket-path->bytes path) - (if (path-string? path) - ;; On all platforms, normal path of up to UNIX-PATH-MAX bytes after - ;; conversion to absolute is considered valid and shall be accepted. - (let ([bstr (path->bytes (cleanse-path (path->complete-path path)))]) - (and (<= (bytes-length bstr) UNIX-PATH-MAX) bstr)) - - ;; On Linux, paths may be in so-called abstract namespace where they - ;; start with #\nul and do not have a corresponding socket file. - ;; We accept such paths only as byte strings because we don't know - ;; the correct encoding. - (and (eq? platform 'linux) - (bytes? path) - (> (bytes-length path) 0) - (<= (bytes-length path) UNIX-PATH-MAX) - (= (bytes-ref path 0) 0) - path))) - - -(define (make-sockaddr path-bytes) - (case platform - [(linux) - (make-linux_sockaddr_un AF-UNIX path-bytes)] - [(macosx) - (make-macosx_sockaddr_un (bytes-length path-bytes) AF-UNIX path-bytes)])) - - -(define (unix-socket-connect path) - (unless platform - (error* 'unix-socket-connect - "unix domain sockets are not supported on this platform")) - - (when (path-string? path) - (security-guard-check-file 'unix-socket-connect path '(read write))) - - (let* ([path-bytes (unix-socket-path->bytes path)] - [sockaddr (make-sockaddr path-bytes)] - [addrlen (+ (ctype-sizeof _ushort) (bytes-length path-bytes))] - [socket-fd (socket AF-UNIX SOCK-STREAM 0)]) - (unless (positive? socket-fd) - (let ([errno (saved-errno)]) - (error* 'unix-socket-connect - "failed to create socket" - "errno" errno - '("error" maybe) (strerror_r errno)))) - - (unless (zero? (connect socket-fd sockaddr addrlen)) - (close socket-fd) - (let ([errno (saved-errno)]) - (error* 'unix-socket-connect - "failed to connect socket" - '("path" value) path - "errno" errno - '("error" maybe) (strerror_r errno)))) - - (with-handlers ([(lambda (e) #t) - (lambda (exn) - (close socket-fd) - (raise exn))]) - (scheme_make_fd_output_port socket-fd 'unix-socket #f #f #t)))) From 7371ab0cc2e40d392982b8a9e2299ef7e54a7fb7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Aug 2015 14:07:32 -0600 Subject: [PATCH 074/381] remove accidentally added file --- racket/collects/racket/private/qar.rkt | 501 ------------------------- 1 file changed, 501 deletions(-) delete mode 100644 racket/collects/racket/private/qar.rkt diff --git a/racket/collects/racket/private/qar.rkt b/racket/collects/racket/private/qar.rkt deleted file mode 100644 index 0a0bcc5da5..0000000000 --- a/racket/collects/racket/private/qar.rkt +++ /dev/null @@ -1,501 +0,0 @@ - -;;---------------------------------------------------------------------- -;; quasiquote, and, or - -(module qq-and-or '#%kernel - (#%require (for-syntax "stx.rkt" '#%kernel)) - - (define-syntaxes (let*-values let let* letrec) - (let-values ([(lambda-stx) (quote-syntax lambda-stx)] - [(letrec-values-stx) (quote-syntax letrec-values)] - [(check-for-duplicates) - (lambda (new-bindings sel stx) - (define-values (id-in-list?) - (lambda (id l) - (if (null? l) - #f - (if (bound-identifier=? id (car l)) - #t - (id-in-list? id (cdr l)))))) - (if ((length new-bindings) . > . 5) - (let-values ([(ht) (make-hasheq)]) - (letrec-values ([(check) (lambda (l) - (if (null? l) - (void) - (let-values ([(id) (sel (car l))]) - (let-values ([(idl) (hash-ref ht (syntax-e id) null)]) - (if (id-in-list? id idl) - (raise-syntax-error - #f - "duplicate identifier" - stx - id) - (begin - (hash-set! ht (syntax-e id) (cons id idl)) - (check (cdr l))))))))]) - (check new-bindings))) - (letrec-values ([(check) (lambda (l accum) - (if (null? l) - (void) - (let-values ([(id) (sel (car l))]) - (if (id-in-list? id accum) - (raise-syntax-error - #f - "duplicate identifier" - stx - id) - (check (cdr l) (cons id accum))))))]) - (check new-bindings null))))]) - (let-values ([(go) - (lambda (stx named? star? target) - (define-values (stx-cadr) (lambda (x) (stx-car (stx-cdr x)))) - (define-values (stx-2list?) - (lambda (x) - (if (stx-pair? x) - (if (stx-pair? (stx-cdr x)) - (stx-null? (stx-cdr (stx-cdr x))) - #f) - #f))) - (let-values ([(maybe-msg) - (if (not (stx-list? stx)) - "" - (let-values ([(tail1) (stx-cdr stx)]) - (if (stx-null? tail1) - (if named? - "(missing name or binding pairs)" - "(missing binding pairs)") - (if (stx-null? (stx-cdr tail1)) - (if named? - "(missing binding pairs or body)" - "(missing body)") - (if named? - (if (symbol? (syntax-e (stx-car tail1))) - (if (stx-null? (stx-cdr (stx-cdr tail1))) - "(missing body)" - #f) - #f) - #f)))))]) - (if maybe-msg - (raise-syntax-error #f (string-append "bad syntax " maybe-msg) stx) - (void))) - (let-values ([(name) (if named? - (let-values ([(n) (stx-cadr stx)]) - (if (symbol? (syntax-e n)) - n - #f)) - #f)]) - (let-values ([(bindings) (stx->list (stx-cadr (if name - (stx-cdr stx) - stx)))] - [(body) (stx-cdr (stx-cdr (if name - (stx-cdr stx) - stx)))]) - (if (not bindings) - (raise-syntax-error - #f - "bad syntax (not a sequence of identifier--expression bindings)" - stx - (stx-cadr stx)) - (let-values ([(new-bindings) - (letrec-values ([(loop) - (lambda (l) - (if (null? l) - null - (let-values ([(binding) (car l)]) - (cons - (if (stx-2list? binding) - (if (symbol? (syntax-e (stx-car binding))) - (if name - (cons (stx-car binding) - (stx-cadr binding)) - (datum->syntax - lambda-stx - (cons (cons (stx-car binding) - null) - (stx-cdr binding)) - binding)) - (raise-syntax-error - #f - "bad syntax (not an identifier)" - stx - (stx-car binding))) - (raise-syntax-error - #f - "bad syntax (not an identifier and expression for a binding)" - stx - binding)) - (loop (cdr l))))))]) - (loop bindings))]) - (if star? - (void) - (check-for-duplicates new-bindings - (if name - car - (lambda (v) (stx-car (stx-car v)))) - stx)) - (datum->syntax - lambda-stx - (if name - (apply list - (list - (quote-syntax letrec-values) - (list - (list - (list name) - (list* (quote-syntax lambda) - (apply list (map car new-bindings)) - body))) - name) - (map cdr new-bindings)) - (list* target - new-bindings - body)) - stx))))))]) - (values - (lambda (stx) - (define-values (bad-syntax) - (lambda () - (raise-syntax-error #f "bad syntax" stx))) - (define-values (l) (syntax->list stx)) - (if (not l) (bad-syntax) (void)) - (if ((length l) . < . 3) (bad-syntax) (void)) - (define-values (bindings) (syntax->list (cadr l))) - (if (not bindings) (raise-syntax-error #f "bad syntax" stx (cadr l)) (void)) - (for-each (lambda (binding) - (define-values (l) (syntax->list binding)) - (if (if (not l) - #t - (not (= 2 (length l)))) - (raise-syntax-error #f "bad syntax" stx binding) - (void)) - (define-values (vars) (syntax->list (car l))) - (if (not vars) (raise-syntax-error #f "bad syntax" stx (car l)) (void)) - (for-each (lambda (var) - (if (not (symbol? (syntax-e var))) - (raise-syntax-error - #f - "bad syntax (not an identifier)" - stx - var) - (void))) - vars) - (check-for-duplicates vars values stx)) - bindings) - (define-values (gen) - (lambda (bindings) - (if (null? bindings) - (list* (quote-syntax let-values) '() (cddr l)) - (list (quote-syntax let-values) (list (car bindings)) (gen (cdr bindings)))))) - (datum->syntax #f (gen bindings) stx stx)) - (lambda (stx) (go stx #t #f (quote-syntax let-values))) - (lambda (stx) (go stx #f #t (quote-syntax let*-values))) - (lambda (stx) (go stx #f #f (quote-syntax letrec-values))))))) - - (define-values (qq-append) - (lambda (a b) - (if (list? a) - (append a b) - (raise-argument-error 'unquote-splicing "list?" a)))) - - (define-syntaxes (quasiquote) - (let-values ([(here) (quote-syntax here)] ; id with module bindings, but not lexical - [(unquote-stx) (quote-syntax unquote)] - [(unquote-splicing-stx) (quote-syntax unquote-splicing)]) - (lambda (in-form) - (if (identifier? in-form) - (raise-syntax-error #f "bad syntax" in-form) - (void)) - (let-values - (((form) (if (stx-pair? (stx-cdr in-form)) - (if (stx-null? (stx-cdr (stx-cdr in-form))) - (stx-car (stx-cdr in-form)) - (raise-syntax-error #f "bad syntax" in-form)) - (raise-syntax-error #f "bad syntax" in-form))) - ((normal) - (lambda (x old) - (if (eq? x old) - (if (stx-null? x) - (quote-syntax ()) - (list (quote-syntax quote) x)) - x))) - ((apply-cons) - (lambda (a d) - (if (stx-null? d) - (list (quote-syntax list) a) - (if (if (pair? d) - (if (free-identifier=? (quote-syntax list) (car d)) - #t - (free-identifier=? (quote-syntax list*) (car d))) - #f) - (list* (car d) a (cdr d)) - (list (quote-syntax list*) a d)))))) - (datum->syntax - here - (normal - (letrec-values - (((qq) - (lambda (x level) - (let-values - (((qq-list) - (lambda (x level) - (let-values - (((old-first) (stx-car x))) - (let-values - (((old-second) (stx-cdr x))) - (let-values - (((first) (qq old-first level))) - (let-values - (((second) (qq old-second level))) - (let-values - () - (if (if (eq? first old-first) - (eq? second old-second) - #f) - x - (apply-cons - (normal first old-first) - (normal second old-second))))))))))) - (if (stx-pair? x) - (let-values - (((first) (stx-car x))) - (if (if (if (identifier? first) - (free-identifier=? first unquote-stx) - #f) - (stx-list? x) - #f) - (let-values - (((rest) (stx-cdr x))) - (if (let-values - (((g35) (not (stx-pair? rest)))) - (if g35 g35 (not (stx-null? (stx-cdr rest))))) - (raise-syntax-error - 'unquote - "expects exactly one expression" - in-form - x) - (void)) - (if (zero? level) - (stx-car rest) - (qq-list x (sub1 level)))) - (if (if (if (identifier? first) - (free-identifier=? first (quote-syntax quasiquote)) - #f) - (stx-list? x) - #f) - (qq-list x (add1 level)) - (if (if (if (identifier? first) - (free-identifier=? first unquote-splicing-stx) - #f) - (stx-list? x) - #f) - (raise-syntax-error - 'unquote-splicing - "invalid context within quasiquote" - in-form - x) - (if (if (stx-pair? first) - (if (identifier? (stx-car first)) - (if (free-identifier=? (stx-car first) - unquote-splicing-stx) - (stx-list? first) - #F) - #f) - #f) - (let-values - (((rest) (stx-cdr first))) - (if (let-values - (((g34) (not (stx-pair? rest)))) - (if g34 - g34 - (not (stx-null? (stx-cdr rest))))) - (raise-syntax-error - 'unquote - "expects exactly one expression" - in-form - x) - (void)) - (let-values - (((uqsd) (stx-car rest)) - ((old-l) (stx-cdr x)) - ((l) (qq (stx-cdr x) level))) - (if (zero? level) - (let-values - (((l) (normal l old-l))) - (if (stx-null? l) - uqsd - (list (quote-syntax qq-append) - uqsd l))) - (let-values - (((restx) (qq-list rest (sub1 level)))) - (let-values - () - (if (if (eq? l old-l) - (eq? restx rest) - #f) - x - (apply-cons - (apply-cons - (quote-syntax (quote unquote-splicing)) - (normal restx rest)) - (normal l old-l)))))))) - (qq-list x level)))))) - (if (if (syntax? x) - (vector? (syntax-e x)) - #f) - (let-values - (((l) (vector->list (syntax-e x)))) - ;; special case: disallow #(unquote ) - (if (stx-pair? l) - (let-values ([(first) (stx-car l)]) - (if (identifier? first) - (if (free-identifier=? first unquote-stx) - (raise-syntax-error - 'unquote - "invalid context within quasiquote" - in-form - first) - (void)) - (void))) - (void)) - (let-values - (((l2) (qq l level))) - (if (eq? l l2) - x - (list (quote-syntax list->vector) l2)))) - (if (if (syntax? x) (box? (syntax-e x)) #f) - (let-values - (((v) (unbox (syntax-e x)))) - (let-values - (((qv) (qq v level))) - (if (eq? v qv) - x - (list (quote-syntax box) qv)))) - (if (if (syntax? x) - (if (struct? (syntax-e x)) - (prefab-struct-key (syntax-e x)) - #f) - #f) - ;; pre-fab struct - (let-values - (((l) (cdr (vector->list (struct->vector (syntax-e x)))))) - (let-values - (((l2) (qq l level))) - (if (eq? l l2) - x - (list (quote-syntax apply) - (quote-syntax make-prefab-struct) - (list (quote-syntax quote) - (prefab-struct-key (syntax-e x))) - l2)))) - ;; hash[eq[v]] - (if (if (syntax? x) - (hash? (syntax-e x)) - #f) - (letrec-values - (((qq-hash-assocs) - (lambda (x level) - (if (null? x) - x - (let-values - (((pair) (car x))) - (let-values ([(val) - (qq (datum->syntax here (cdr pair)) level)] - [(rest) - (qq-hash-assocs (cdr x) level)]) - (if (if (eq? val (cdr pair)) - (eq? rest (cdr x)) - #f) - x - (apply-cons - (list (quote-syntax list*) - (list (quote-syntax quote) - (datum->syntax here (car pair))) - (if (eq? val (cdr pair)) - (list (quote-syntax quote) - val) - val)) - (if (eq? rest (cdr x)) - (list (quote-syntax quote) - rest) - rest))))))))) - (let-values (((l0) (hash-map (syntax-e x) cons))) - (let-values - (((l) (qq-hash-assocs l0 level))) - (if (eq? l0 l) - x - (list (if (hash-eq? (syntax-e x)) - (quote-syntax make-immutable-hasheq) - (if (hash-eqv? (syntax-e x)) - (quote-syntax make-immutable-hasheqv) - (quote-syntax make-immutable-hash))) - l))))) - x))))))))) - (qq form 0)) - form) - in-form))))) - - (define-syntaxes (and) - (let-values ([(here) (quote-syntax here)]) - (lambda (x) - (if (not (stx-list? x)) - (raise-syntax-error #f "bad syntax" x) - (void)) - (let-values ([(e) (stx-cdr x)]) - (if (stx-null? e) - (quote-syntax #t) - (if (if (stx-pair? e) - (stx-null? (stx-cdr e)) - #t) - (datum->syntax - here - (list (quote-syntax #%expression) - (stx-car e)) - x) - (datum->syntax - here - (list (quote-syntax if) - (stx-car e) - (cons (quote-syntax and) - (stx-cdr e)) - (quote-syntax #f)) - x))))))) - - (define-syntaxes (or) - (let-values ([(here) (quote-syntax here)]) - (lambda (x) - (if (identifier? x) - (raise-syntax-error #f "bad syntax" x) - (void)) - (let-values ([(e) (stx-cdr x)]) - (if (stx-null? e) - (quote-syntax #f) - (if (if (stx-pair? e) - (stx-null? (stx-cdr e)) - #f) - (datum->syntax - here - (list (quote-syntax #%expression) - (stx-car e)) - x) - (if (stx-list? e) - (let-values ([(tmp) 'or-part]) - (datum->syntax - here - (list (quote-syntax let) (list - (list - tmp - (stx-car e))) - (list (quote-syntax if) - tmp - tmp - (cons (quote-syntax or) - (stx-cdr e)))) - x)) - (raise-syntax-error - #f - "bad syntax" - x)))))))) - - (#%provide let*-values - let let* letrec - quasiquote and or)) From 674ab66d7b33f4a526cad4491acfc28fe5791194 Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Tue, 18 Aug 2015 14:03:24 -0600 Subject: [PATCH 075/381] Added support for ref args in lifts to unresolver --- racket/src/racket/src/mzmark_resolve.inc | 2 ++ racket/src/racket/src/mzmarksrc.c | 1 + racket/src/racket/src/resolve.c | 31 +++++++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/mzmark_resolve.inc b/racket/src/racket/src/mzmark_resolve.inc index 45ad01b3b3..d9c7b662bd 100644 --- a/racket/src/racket/src/mzmark_resolve.inc +++ b/racket/src/racket/src/mzmark_resolve.inc @@ -63,6 +63,7 @@ static int mark_unresolve_info_MARK(void *p, struct NewGC *gc) { gcMARK2(i->toplevels, gc); gcMARK2(i->definitions, gc); gcMARK2(i->ref_args, gc); + gcMARK2(i->ref_lifts, gc); return gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); @@ -81,6 +82,7 @@ static int mark_unresolve_info_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(i->toplevels, gc); gcFIXUP2(i->definitions, gc); gcFIXUP2(i->ref_args, gc); + gcFIXUP2(i->ref_lifts, gc); return gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index c48bffab91..3a05bbc505 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -1315,6 +1315,7 @@ mark_unresolve_info { gcMARK2(i->toplevels, gc); gcMARK2(i->definitions, gc); gcMARK2(i->ref_args, gc); + gcMARK2(i->ref_lifts, gc); size: gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index df6d5575bd..4f83e2c75c 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -3229,6 +3229,8 @@ typedef struct Unresolve_Info { Scheme_Hash_Table *toplevels; Scheme_Object *definitions; mzshort *ref_args; + int lift_offset; + Scheme_Hash_Table *ref_lifts; } Unresolve_Info; static Scheme_Object *unresolve_expr(Scheme_Object *e, Unresolve_Info *ui, int as_rator); @@ -3257,6 +3259,8 @@ static Unresolve_Info *new_unresolve_info(Scheme_Prefix *prefix) ht = scheme_make_hash_table(SCHEME_hash_ptr); ui->toplevels = ht; ui->definitions = scheme_null; + ht = scheme_make_hash_table(SCHEME_hash_ptr); + ui->ref_lifts = ht; return ui; } @@ -3405,7 +3409,7 @@ static Scheme_Object *unresolve_closure_data_2(Scheme_Closure_Data *rdata, Unres LOG_UNRESOLVE(printf("ref_args[%d] = %d\n", ui->stack_pos - i - 1, scheme_boxmap_get(rdata->closure_map, i, rdata->closure_size))); ui->ref_args[ui->stack_pos - i - 1] = - scheme_boxmap_get(rdata->closure_map, i, rdata->closure_size); + scheme_boxmap_get(rdata->closure_map, i, rdata->closure_size) == CLOS_TYPE_BOXED; } } @@ -3539,6 +3543,17 @@ static Scheme_Object *unresolve_define_values(Scheme_Object *e, Unresolve_Info * Scheme_Object *vars = scheme_null; Scheme_Object *vec, *val, *tl; int i; + + if (SCHEME_VEC_SIZE(e) == 2) { + int pos = SCHEME_TOPLEVEL_POS(SCHEME_VEC_ELS(e)[1]); + if (pos >= ui->lift_offset) { + Scheme_Closure_Data *data = (Scheme_Closure_Data *)SCHEME_VEC_ELS(e)[0]; + if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) { + scheme_hash_set(ui->ref_lifts, scheme_make_integer(pos), (Scheme_Object *)data); + } + } + } + LOG_UNRESOLVE(printf("define-values-size!!!: %d\n", (int)SCHEME_VEC_SIZE(e))); for (i = SCHEME_VEC_SIZE(e); --i;) { @@ -3753,6 +3768,7 @@ static Comp_Prefix *unresolve_prefix(Resolve_Prefix *rp, Unresolve_Info *ui) { #endif cp->num_toplevels = 0; cp->toplevels = NULL; + ui->lift_offset = rp->num_toplevels; for (i = 0; i < rp->num_toplevels; i++) { if (SCHEME_SYMBOLP(rp->toplevels[i])) { Scheme_Object *mv; @@ -4100,12 +4116,19 @@ static Scheme_Sequence *unresolve_let_value(Scheme_Let_Value *lv, Unresolve_Info Scheme_App_Rec *maybe_unresolve_app_refs(Scheme_App_Rec *app, Unresolve_Info *ui) { Scheme_Object *rator; + Scheme_Closure_Data *data = NULL; rator = app->args[0]; - /* TODO: check if in ui->closures */ if (SAME_TYPE(SCHEME_TYPE(rator), scheme_closure_type) && (SCHEME_CLOSURE_DATA_FLAGS((SCHEME_COMPILED_CLOS_CODE(rator))) & CLOS_HAS_TYPED_ARGS)) { - Scheme_Closure_Data *data = SCHEME_COMPILED_CLOS_CODE(rator); + data = SCHEME_COMPILED_CLOS_CODE(rator); + } + + if (SAME_TYPE(SCHEME_TYPE(rator), scheme_toplevel_type)) { + data = (Scheme_Closure_Data *)scheme_hash_get(ui->ref_lifts, scheme_make_integer(SCHEME_TOPLEVEL_POS(rator))); + } + + if (data) { Scheme_App_Rec *new_app; Scheme_Object *new_rator; int i; @@ -4116,7 +4139,7 @@ Scheme_App_Rec *maybe_unresolve_app_refs(Scheme_App_Rec *app, Unresolve_Info *ui for(i = 0; i < data->num_params; i++) { LOG_UNRESOLVE(printf("%d: %d\n", i, scheme_boxmap_get(data->closure_map, i, data->closure_size))); LOG_UNRESOLVE(printf("ui->stack_pos = %d, argpos = %d, i = %d\n", ui->stack_pos, SCHEME_LOCAL_POS(app->args[i + 1]), i)); - if ((scheme_boxmap_get(data->closure_map, i, data->closure_size) & CLOS_TYPE_BOXED) && + if ((scheme_boxmap_get(data->closure_map, i, data->closure_size) == CLOS_TYPE_BOXED) && SAME_TYPE(SCHEME_TYPE(app->args[i + 1]), scheme_local_type) && !ui->ref_args[ui->stack_pos - SCHEME_LOCAL_POS(app->args[i + 1]) - 1]) { Scheme_Case_Lambda *cl; From 5c9995ee9aa1c928e52fc6c51651671219ffd619 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 18 Aug 2015 17:03:58 -0500 Subject: [PATCH 076/381] Move unstable/custom-write to unstable-lib. --- racket/collects/data/integer-set.rkt | 2 +- racket/collects/unstable/custom-write.rkt | 70 ----------------------- 2 files changed, 1 insertion(+), 71 deletions(-) delete mode 100644 racket/collects/unstable/custom-write.rkt diff --git a/racket/collects/data/integer-set.rkt b/racket/collects/data/integer-set.rkt index eb098e82c1..f2300fc26e 100644 --- a/racket/collects/data/integer-set.rkt +++ b/racket/collects/data/integer-set.rkt @@ -5,7 +5,7 @@ (require racket/contract/base racket/match racket/stream - unstable/custom-write) + racket/struct) (provide well-formed-set? (contract-out diff --git a/racket/collects/unstable/custom-write.rkt b/racket/collects/unstable/custom-write.rkt deleted file mode 100644 index de68d943f9..0000000000 --- a/racket/collects/unstable/custom-write.rkt +++ /dev/null @@ -1,70 +0,0 @@ -#lang racket/base -(require racket/struct - racket/pretty - racket/match - racket/sequence - racket/contract/base) -(provide make-constructor-style-printer - (contract-out - [prop:auto-custom-write - (struct-type-property/c 'constructor)])) - -;; TODO: deal with super struct types better -;; - see "Problem" below - -#| -Constructor-style printer - - eg 'set' printer - - in mode 0, "(" + constructor + { " " + elem }* + ")" - - else, "#<" + constructor + ":" + ... + ">" - - print elems w/ same mode - - never quotable -|# - -(define-values (prop:auto-custom-write auto-custom-write? auto-custom-write-proc) - (make-struct-type-property - 'auto-custom-write - (lambda (val info) - (case val - ((constructor) - (struct-info->get-constructor+get-contents info)))) - (list (cons prop:custom-print-quotable - (lambda (auto-write-val) 'never)) - (cons prop:custom-write - (lambda (auto-write-val) - (make-constructor-style-printer - (car auto-write-val) - (cdr auto-write-val))))))) - -(define (struct-info->get-constructor+get-contents info) - (match info - [(list name init-ct auto-ct accessor mutator imms super skipped?) - (let ([get-super-contents - ;; Problem: if super type was not transparent (to current - ;; inspector), then we don't get it (ie, skipped? is #t), and so we - ;; can't tell if super type also has prop:auto-custom-write - ;; property. - (cond [skipped? - (error 'prop:auto-custom-write - "struct super type is inaccessible")] - [(not super) - #f] - [(auto-custom-write? super) - (cdr (auto-custom-write-proc super))] - [else - (let ([super-getters - (struct-info->get-constructor+get-contents - (call-with-values (lambda () (struct-type-info super)) - list))]) - (cdr super-getters))])]) - (define (get-constructor obj) - name) - (define (get-new-contents obj) - (for/list ([i (in-range (+ init-ct auto-ct))]) - (accessor obj i))) - (cons get-constructor - (if get-super-contents - (lambda (obj) - (sequence-append (get-super-contents obj) - (get-new-contents obj))) - get-new-contents)))])) From 13b6a98de66b73c456fabcb632362ae5128dd53c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 18 Aug 2015 17:09:52 -0500 Subject: [PATCH 077/381] Move docs for `make-constructor-style-printer` from unstable docs. --- .../scribblings/reference/struct.scrbl | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pkgs/racket-doc/scribblings/reference/struct.scrbl b/pkgs/racket-doc/scribblings/reference/struct.scrbl index bf41e7843b..517318a8e3 100644 --- a/pkgs/racket-doc/scribblings/reference/struct.scrbl +++ b/pkgs/racket-doc/scribblings/reference/struct.scrbl @@ -606,6 +606,44 @@ key, @racket[#f] otherwise. See @racket[make-prefab-struct] for a description of valid key shapes.} +@subsection{Additional Structure Utilities} + +@note-lib-only[racket/struct] + +@defproc[(make-constructor-style-printer + [get-constructor (-> any/c (or/c symbol? string?))] + [get-contents (-> any/c sequence?)]) + (-> any/c output-port? (or/c #t #f 0 1) void?)]{ + +Produces a function suitable as a value for @racket[prop:custom-write]. The +function prints values in ``constructor style.'' When the value is +@racket[print]ed as an expression, it is shown as an application of the +constructor (as returned by @racket[get-constructor]) to the contents (as +returned by @racket[get-contents]). When given to @racket[write], it is shown as +an unreadable value with the constructor separated from the contents by a colon. + +@(struct-eval '(require racket/struct racket/pretty)) + +@examples[#:eval struct-eval +(struct point (x y) + #:property prop:custom-write + (make-constructor-style-printer + (lambda (obj) 'point) + (lambda (obj) (list (point-x obj) (point-y obj))))) +(print (point 1 2)) +(write (point 1 2)) +] + +The function also cooperates with @racket[pretty-print]: + +@examples[#:eval struct-eval +(parameterize ((pretty-print-columns 10)) + (pretty-print (point #e3e6 #e4e6))) +(parameterize ((pretty-print-columns 10)) + (pretty-write (point #e3e6 #e4e6))) +] +} + @;------------------------------------------------------------------------ @section[#:tag "structinfo"]{Structure Type Transformer Binding} From 5ce75816c5d9c260a052fdef1ed311c0071acc49 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 19 Aug 2015 13:46:00 -0500 Subject: [PATCH 078/381] Move `struct->list` to `racket/struct`. --- racket/collects/racket/struct.rkt | 28 +++++++++++++++++++++++++++- racket/collects/unstable/struct.rkt | 28 ++-------------------------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/racket/collects/racket/struct.rkt b/racket/collects/racket/struct.rkt index 765e6bca5e..f4d7c855e2 100644 --- a/racket/collects/racket/struct.rkt +++ b/racket/collects/racket/struct.rkt @@ -5,4 +5,30 @@ [make-constructor-style-printer (-> (-> any/c (or/c symbol? string?)) (-> any/c sequence?) - (-> any/c output-port? (or/c #t #f 0 1) void?))])) + (-> any/c output-port? (or/c #t #f 0 1) void?))]) + struct->list) + +(define dummy-value (box 'dummy)) + +;; struct->list : struct? +;; #:on-opaque (or/c 'error 'return-false 'skip) +;; -> (listof any/c) +(define (struct->list s + #:on-opaque [on-opaque 'error]) + (define error-on-opaque? (eq? on-opaque 'error)) + (let ([vec (struct->vector s dummy-value)]) + ;; go through vector backwards, don't traverse 0 (struct name) + (let loop ([index (sub1 (vector-length vec))] + [elems null] + [any-opaque? #f]) + (cond [(positive? index) + (let ([elem (vector-ref vec index)]) + (cond [(eq? elem dummy-value) + (when error-on-opaque? + (raise-type-error 'struct->list "non-opaque struct" s)) + (loop (sub1 index) elems #t)] + [else (loop (sub1 index) (cons elem elems) any-opaque?)]))] + [else + (cond [(and any-opaque? (eq? on-opaque 'return-false)) + #f] + [else elems])])))) diff --git a/racket/collects/unstable/struct.rkt b/racket/collects/unstable/struct.rkt index 7048c395a6..100739b852 100644 --- a/racket/collects/unstable/struct.rkt +++ b/racket/collects/unstable/struct.rkt @@ -1,7 +1,8 @@ #lang racket/base ;; owner: ryanc (require (for-syntax racket/base - racket/struct-info)) + racket/struct-info) + racket/struct) (provide make struct->list (for-syntax get-struct-info)) @@ -49,28 +50,3 @@ ;; use `-W warning'. (And then, if you really want these things to be ;; errors, then perhaps something at the racket level should make it throw ;; errors instead of warnings.) - -(define dummy-value (box 'dummy)) - -;; struct->list : struct? -;; #:on-opaque (or/c 'error 'return-false 'skip) -;; -> (listof any/c) -(define (struct->list s - #:on-opaque [on-opaque 'error]) - (define error-on-opaque? (eq? on-opaque 'error)) - (let ([vec (struct->vector s dummy-value)]) - ;; go through vector backwards, don't traverse 0 (struct name) - (let loop ([index (sub1 (vector-length vec))] - [elems null] - [any-opaque? #f]) - (cond [(positive? index) - (let ([elem (vector-ref vec index)]) - (cond [(eq? elem dummy-value) - (when error-on-opaque? - (raise-type-error 'struct->list "non-opaque struct" s)) - (loop (sub1 index) elems #t)] - [else (loop (sub1 index) (cons elem elems) any-opaque?)]))] - [else - (cond [(and any-opaque? (eq? on-opaque 'return-false)) - #f] - [else elems])])))) From ed70381d705d7051d0ab5732dc1a41d9bcc20e95 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 19 Aug 2015 13:47:36 -0500 Subject: [PATCH 079/381] Move rest of `unstable/struct` to `unstable-lib`. --- racket/collects/unstable/struct.rkt | 52 ----------------------------- 1 file changed, 52 deletions(-) delete mode 100644 racket/collects/unstable/struct.rkt diff --git a/racket/collects/unstable/struct.rkt b/racket/collects/unstable/struct.rkt deleted file mode 100644 index 100739b852..0000000000 --- a/racket/collects/unstable/struct.rkt +++ /dev/null @@ -1,52 +0,0 @@ -#lang racket/base -;; owner: ryanc -(require (for-syntax racket/base - racket/struct-info) - racket/struct) -(provide make - struct->list - (for-syntax get-struct-info)) - -;; get-struct-info : identifier stx -> struct-info-list -(define-for-syntax (get-struct-info id ctx) - (define (bad-struct-name x) - (raise-syntax-error #f "expected struct name" ctx x)) - (unless (identifier? id) - (bad-struct-name id)) - (let ([value (syntax-local-value id (lambda () #f))]) - (unless (struct-info? value) - (bad-struct-name id)) - (extract-struct-info value))) - -;; (make struct-name field-expr ...) -;; Checks that correct number of fields given. -(define-syntax (make stx) - (syntax-case stx () - [(make S expr ...) - (let () - (define info (get-struct-info #'S stx)) - (define constructor (list-ref info 1)) - (define accessors (list-ref info 3)) - (unless (identifier? #'constructor) - (raise-syntax-error #f "constructor not available for struct" stx #'S)) - (unless (andmap identifier? accessors) - (raise-syntax-error #f "incomplete info for struct type" stx #'S)) - (let ([num-slots (length accessors)] - [num-provided (length (syntax->list #'(expr ...)))]) - (unless (= num-provided num-slots) - (raise-syntax-error - #f - (format "wrong number of arguments for struct ~s (expected ~s, got ~s)" - (syntax-e #'S) - num-slots - num-provided) - stx))) - (with-syntax ([constructor constructor]) - (syntax-property #'(constructor expr ...) - 'disappeared-use - #'S)))])) -;; Eli: You give a good point for this, but I'd prefer if the optimizer would -;; detect these, so you'd get the same warnings for constructors too when you -;; use `-W warning'. (And then, if you really want these things to be -;; errors, then perhaps something at the racket level should make it throw -;; errors instead of warnings.) From e5a024b02eef57f4e86649636bfbbf097972c1e0 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 19 Aug 2015 13:50:33 -0500 Subject: [PATCH 080/381] Move `struct->list` docs from unstable docs. --- .../scribblings/reference/struct.scrbl | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pkgs/racket-doc/scribblings/reference/struct.scrbl b/pkgs/racket-doc/scribblings/reference/struct.scrbl index 517318a8e3..806703c1ba 100644 --- a/pkgs/racket-doc/scribblings/reference/struct.scrbl +++ b/pkgs/racket-doc/scribblings/reference/struct.scrbl @@ -644,6 +644,34 @@ The function also cooperates with @racket[pretty-print]: ] } +@defproc[(struct->list [v any/c] + [#:on-opaque on-opaque (or/c 'error 'return-false 'skip) 'error]) + (or/c list? #f)]{ + +Returns a list containing the struct instance @racket[v]'s +fields. Unlike @racket[struct->vector], the struct name itself is not +included. + +If any fields of @racket[v] are inaccessible via the current inspector +the behavior of @racket[struct->list] is determined by +@racket[on-opaque]. If @racket[on-opaque] is @racket['error] (the +default), an error is raised. If it is @racket['return-false], +@racket[struct->list] returns @racket[#f]. If it is @racket['skip], +the inaccessible fields are omitted from the list. + +@examples[#:eval struct-eval +(define-struct open (u v) #:transparent) +(struct->list (make-open 'a 'b)) +(struct->list #s(pre 1 2 3)) +(define-struct (secret open) (x y)) +(struct->list (make-secret 0 1 17 22)) +(struct->list (make-secret 0 1 17 22) #:on-opaque 'return-false) +(struct->list (make-secret 0 1 17 22) #:on-opaque 'skip) +(struct->list 'not-a-struct #:on-opaque 'return-false) +(struct->list 'not-a-struct #:on-opaque 'skip) +] +} + @;------------------------------------------------------------------------ @section[#:tag "structinfo"]{Structure Type Transformer Binding} From ac462be47cd7c87985f5c76ff20e9524e23437d0 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 19 Aug 2015 14:02:48 -0500 Subject: [PATCH 081/381] Fix uses of `unstable/struct`. --- racket/collects/racket/private/serialize.rkt | 2 +- racket/collects/syntax/parse/private/make.rkt | 43 +++++++++++++++++++ .../syntax/parse/private/minimatch.rkt | 4 +- .../collects/syntax/parse/private/parse.rkt | 2 +- .../syntax/parse/private/rep-attrs.rkt | 2 +- .../syntax/parse/private/rep-data.rkt | 2 +- .../syntax/parse/private/rep-patterns.rkt | 2 +- racket/collects/syntax/parse/private/rep.rkt | 3 +- .../syntax/parse/private/runtime-report.rkt | 2 +- .../syntax/private/template-runtime.rkt | 2 +- racket/collects/syntax/strip-context.rkt | 2 +- racket/collects/syntax/template.rkt | 2 +- 12 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 racket/collects/syntax/parse/private/make.rkt diff --git a/racket/collects/racket/private/serialize.rkt b/racket/collects/racket/private/serialize.rkt index 7855eece0b..0c18f2b8da 100644 --- a/racket/collects/racket/private/serialize.rkt +++ b/racket/collects/racket/private/serialize.rkt @@ -1,6 +1,6 @@ (module serialize racket/base (require syntax/modcollapse - unstable/struct + racket/struct racket/list racket/flonum racket/fixnum diff --git a/racket/collects/syntax/parse/private/make.rkt b/racket/collects/syntax/parse/private/make.rkt new file mode 100644 index 0000000000..8a4f744852 --- /dev/null +++ b/racket/collects/syntax/parse/private/make.rkt @@ -0,0 +1,43 @@ +#lang racket/base +(require (for-syntax racket/base + racket/struct-info)) +(provide make) + +;; get-struct-info : identifier stx -> struct-info-list +(define-for-syntax (get-struct-info id ctx) + (define (bad-struct-name x) + (raise-syntax-error #f "expected struct name" ctx x)) + (unless (identifier? id) + (bad-struct-name id)) + (let ([value (syntax-local-value id (lambda () #f))]) + (unless (struct-info? value) + (bad-struct-name id)) + (extract-struct-info value))) + +;; (make struct-name field-expr ...) +;; Checks that correct number of fields given. +(define-syntax (make stx) + (syntax-case stx () + [(make S expr ...) + (let () + (define info (get-struct-info #'S stx)) + (define constructor (list-ref info 1)) + (define accessors (list-ref info 3)) + (unless (identifier? #'constructor) + (raise-syntax-error #f "constructor not available for struct" stx #'S)) + (unless (andmap identifier? accessors) + (raise-syntax-error #f "incomplete info for struct type" stx #'S)) + (let ([num-slots (length accessors)] + [num-provided (length (syntax->list #'(expr ...)))]) + (unless (= num-provided num-slots) + (raise-syntax-error + #f + (format "wrong number of arguments for struct ~s (expected ~s, got ~s)" + (syntax-e #'S) + num-slots + num-provided) + stx))) + (with-syntax ([constructor constructor]) + (syntax-property #'(constructor expr ...) + 'disappeared-use + #'S)))])) diff --git a/racket/collects/syntax/parse/private/minimatch.rkt b/racket/collects/syntax/parse/private/minimatch.rkt index 2e0dc63f7a..d92eb40d22 100644 --- a/racket/collects/syntax/parse/private/minimatch.rkt +++ b/racket/collects/syntax/parse/private/minimatch.rkt @@ -1,6 +1,6 @@ #lang racket/base -(require unstable/struct - (for-syntax racket/base racket/struct-info unstable/struct)) +(require racket/struct + (for-syntax racket/base racket/struct-info racket/struct)) (provide match ?) (define-syntax (match stx) diff --git a/racket/collects/syntax/parse/private/parse.rkt b/racket/collects/syntax/parse/private/parse.rkt index aaf92f3102..807a670856 100644 --- a/racket/collects/syntax/parse/private/parse.rkt +++ b/racket/collects/syntax/parse/private/parse.rkt @@ -16,7 +16,7 @@ racket/syntax racket/stxparam syntax/stx - unstable/struct + racket/struct syntax/parse/private/residual ;; keep abs. path syntax/parse/private/runtime ;; keep abs.path syntax/parse/private/runtime-reflect) ;; keep abs. path diff --git a/racket/collects/syntax/parse/private/rep-attrs.rkt b/racket/collects/syntax/parse/private/rep-attrs.rkt index 746b340198..7996314eaa 100644 --- a/racket/collects/syntax/parse/private/rep-attrs.rkt +++ b/racket/collects/syntax/parse/private/rep-attrs.rkt @@ -3,7 +3,7 @@ racket/contract/base syntax/private/id-table racket/syntax - unstable/struct) + "make.rkt") #| An IAttr is (make-attr identifier number boolean) diff --git a/racket/collects/syntax/parse/private/rep-data.rkt b/racket/collects/syntax/parse/private/rep-data.rkt index 977cc57bf5..8e309c1997 100644 --- a/racket/collects/syntax/parse/private/rep-data.rkt +++ b/racket/collects/syntax/parse/private/rep-data.rkt @@ -5,7 +5,7 @@ syntax/private/id-table racket/syntax syntax/parse/private/residual-ct ;; keep abs. path - unstable/struct + "make.rkt" "minimatch.rkt" "kws.rkt" "rep-attrs.rkt" diff --git a/racket/collects/syntax/parse/private/rep-patterns.rkt b/racket/collects/syntax/parse/private/rep-patterns.rkt index 06f71564dd..2fecadf19c 100644 --- a/racket/collects/syntax/parse/private/rep-patterns.rkt +++ b/racket/collects/syntax/parse/private/rep-patterns.rkt @@ -2,7 +2,7 @@ (require syntax/parse/private/residual-ct ;; keep abs. path "rep-attrs.rkt" "kws.rkt" - unstable/struct + "make.rkt" (for-syntax racket/base syntax/stx racket/syntax)) diff --git a/racket/collects/syntax/parse/private/rep.rkt b/racket/collects/syntax/parse/private/rep.rkt index a1aaf36230..35d9277b5b 100644 --- a/racket/collects/syntax/parse/private/rep.rkt +++ b/racket/collects/syntax/parse/private/rep.rkt @@ -6,12 +6,13 @@ syntax/parse/private/runtime) racket/list racket/contract/base + "make.rkt" "minimatch.rkt" syntax/private/id-table syntax/stx syntax/keyword racket/syntax - unstable/struct + racket/struct "txlift.rkt" "rep-attrs.rkt" "rep-data.rkt" diff --git a/racket/collects/syntax/parse/private/runtime-report.rkt b/racket/collects/syntax/parse/private/runtime-report.rkt index ac7078d7fd..22007719eb 100644 --- a/racket/collects/syntax/parse/private/runtime-report.rkt +++ b/racket/collects/syntax/parse/private/runtime-report.rkt @@ -2,7 +2,7 @@ (require racket/list racket/format syntax/stx - unstable/struct + racket/struct unstable/error syntax/srcloc "minimatch.rkt" diff --git a/racket/collects/syntax/private/template-runtime.rkt b/racket/collects/syntax/private/template-runtime.rkt index 344a3a25b9..227ca249db 100644 --- a/racket/collects/syntax/private/template-runtime.rkt +++ b/racket/collects/syntax/private/template-runtime.rkt @@ -1,6 +1,6 @@ #lang racket/base (require "../stx.rkt" - unstable/struct) + racket/struct) (provide template-map-apply) diff --git a/racket/collects/syntax/strip-context.rkt b/racket/collects/syntax/strip-context.rkt index a316cad8b3..6e2f2f4de7 100644 --- a/racket/collects/syntax/strip-context.rkt +++ b/racket/collects/syntax/strip-context.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require unstable/struct) +(require racket/struct) (provide strip-context replace-context) diff --git a/racket/collects/syntax/template.rkt b/racket/collects/syntax/template.rkt index 3351e30302..c4bac0e72a 100644 --- a/racket/collects/syntax/template.rkt +++ b/racket/collects/syntax/template.rkt @@ -1,6 +1,6 @@ #lang racket/base (require "stx.rkt" - unstable/struct + racket/struct (for-template racket/base "private/template-runtime.rkt")) From d63d3e603e4d5688ea7a7fd264bda10b54ea2aa3 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 19 Aug 2015 19:13:41 -0400 Subject: [PATCH 082/381] Increase timeout. --- pkgs/racket-test/tests/racket/stress/dict.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/racket/stress/dict.rkt b/pkgs/racket-test/tests/racket/stress/dict.rkt index e2ca7895ad..0984c1acb6 100644 --- a/pkgs/racket-test/tests/racket/stress/dict.rkt +++ b/pkgs/racket-test/tests/racket/stress/dict.rkt @@ -115,4 +115,5 @@ (module+ test (module config info - (define random? #t))) + (define random? #t) + (define timeout 300))) From 0ba2d30fed1af7be6b1abb63a55d87520927f64e Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 20 Aug 2015 14:12:56 -0400 Subject: [PATCH 083/381] Increse place-channel test timeout. --- pkgs/racket-test/tests/racket/place-channel.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/racket/place-channel.rkt b/pkgs/racket-test/tests/racket/place-channel.rkt index 1ece2ce4db..4a5c35b851 100644 --- a/pkgs/racket-test/tests/racket/place-channel.rkt +++ b/pkgs/racket-test/tests/racket/place-channel.rkt @@ -452,4 +452,5 @@ (module+ test (module config info - (define random? #t))) + (define random? #t) + (define timeout 300))) From 725536b8b425966a0d70d4a44640cbc1e73aaa50 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 20 Aug 2015 15:08:57 -0500 Subject: [PATCH 084/381] add missing contract checking --- .../tests/racket/contract/arrow-neg-party.rkt | 31 ++++- .../contract/private/arrow-val-first.rkt | 127 ++++++++++-------- 2 files changed, 104 insertions(+), 54 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt b/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt index 8548039b3d..43bc166f8a 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt @@ -241,4 +241,33 @@ #:port [port #f]) (list user db password port))) 'neg #:database "db" #:password "password" #:user "user") - (list "user" "db" "password" #f))) + (list "user" "db" "password" #f)) + + (test/pos-blame + '->*neg-party19 + '((neg-party-fn + (->* (any/c) (#:kw any/c) boolean?) + (λ (x #:kw [kw 0]) x)) + 'neg 42)) + + (test/neg-blame + '->*neg-party20 + '((neg-party-fn + (->* (any/c) (#:kw any/c) #:pre #f any/c) + (λ (x #:kw [kw 0]) x)) + 'neg 42)) + + (test/pos-blame + '->*neg-party21 + '((neg-party-fn + (->* (any/c) (#:kw any/c) any/c #:post #f) + (λ (x #:kw [kw 0]) x)) + 'neg 42)) + + (test/spec-passed/result + '->*neg-party22 + '((neg-party-fn + (->* (any/c) (#:kw any/c) any) + (λ (x #:kw [kw 0]) x)) + 'neg 42) + 42)) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 1d4867ab66..46c3d4208b 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -194,7 +194,7 @@ [(the-call ...) #'(f ((regb arg-x) neg-party) ... kwd-arg-exps ...)] [(pre-check ...) (if pre - (list #`(check-pre-cond #,pre blame neg-party f)) + (list #`(check-pre-cond #,pre blame neg-party f)) (list))] [(post-check ...) (if post @@ -268,70 +268,91 @@ #`(case-lambda #,@case-lambda-clauses)])] [else #`(make-checking-proc f blame + #,(if pre pre #'#f) '(#,@mandatory-kwds) (list kb ...) '(#,@optional-kwds) (list okb ...) #,(length regular-args) (list regb ... optb ...) - #,(if rest #'restb #'#f))])) + #,(if rest #'restb #'#f) + #,(if post post #'#f) + #,(if rngs #'(list rb ...) #'#f))])) #`(λ (blame f regb ... optb ... kb ... okb ... rb ... #,@(if rest (list #'restb) '())) #,body-proc))))) -(define (make-checking-proc f blame +(define (make-checking-proc f blame pre original-mandatory-kwds kbs original-optional-kwds okbs - minimum-arg-count rbs rest-ctc) + minimum-arg-count rbs rest-ctc + post rngs) (make-keyword-procedure (λ (actual-kwds actual-kwd-args neg-party . regular-args) (check-arg-count minimum-arg-count (length rbs) regular-args f blame neg-party rest-ctc) (check-keywords original-mandatory-kwds original-optional-kwds actual-kwds f blame neg-party) - (keyword-apply - f - actual-kwds - (let loop ([kwds actual-kwds] - [kwd-args actual-kwd-args] - [mandatory-kwds original-mandatory-kwds] - [optional-kwds original-optional-kwds] - [kbs kbs] - [okbs okbs]) - (cond - [(null? kwd-args) '()] - [else - (define kwd (car kwds)) - (define kwd-arg (car kwd-args)) - (cond - [(and (pair? mandatory-kwds) - (equal? (car mandatory-kwds) kwd)) - (cons (((car kbs) kwd-arg) neg-party) - (loop (cdr kwds) - (cdr kwd-args) - (cdr mandatory-kwds) - optional-kwds - (cdr kbs) - okbs))] - [(and (pair? optional-kwds) - (equal? (car optional-kwds) kwd)) - (cons (((car okbs) kwd-arg) neg-party) - (loop (cdr kwds) - (cdr kwd-args) - mandatory-kwds - (cdr optional-kwds) - kbs - (cdr okbs)))] - [(pair? optional-kwds) - (loop kwds kwd-args mandatory-kwds (cdr optional-kwds) kbs (cdr okbs))] - [else - (error 'arrow-val-first.rkt - (string-append - "internal error:\n f ~s\n actual-kwds ~s" - "\n mandatory-kwds ~s\n optional-kwds ~s\n neg-party ~s") - f actual-kwds original-mandatory-kwds original-optional-kwds neg-party)])])) - (let loop ([regular-args regular-args] - [rbs rbs]) - (cond - [(null? regular-args) '()] - [(null? rbs) ((rest-ctc regular-args) neg-party)] - [else - (cons (((car rbs) (car regular-args)) neg-party) - (loop (cdr regular-args) (cdr rbs)))])))))) + (define (mk-call) + (keyword-apply + f + actual-kwds + (let loop ([kwds actual-kwds] + [kwd-args actual-kwd-args] + [mandatory-kwds original-mandatory-kwds] + [optional-kwds original-optional-kwds] + [kbs kbs] + [okbs okbs]) + (cond + [(null? kwd-args) '()] + [else + (define kwd (car kwds)) + (define kwd-arg (car kwd-args)) + (cond + [(and (pair? mandatory-kwds) + (equal? (car mandatory-kwds) kwd)) + (cons (((car kbs) kwd-arg) neg-party) + (loop (cdr kwds) + (cdr kwd-args) + (cdr mandatory-kwds) + optional-kwds + (cdr kbs) + okbs))] + [(and (pair? optional-kwds) + (equal? (car optional-kwds) kwd)) + (cons (((car okbs) kwd-arg) neg-party) + (loop (cdr kwds) + (cdr kwd-args) + mandatory-kwds + (cdr optional-kwds) + kbs + (cdr okbs)))] + [(pair? optional-kwds) + (loop kwds kwd-args mandatory-kwds (cdr optional-kwds) kbs (cdr okbs))] + [else + (error 'arrow-val-first.rkt + (string-append + "internal error:\n f ~s\n actual-kwds ~s" + "\n mandatory-kwds ~s\n optional-kwds ~s\n neg-party ~s") + f actual-kwds original-mandatory-kwds original-optional-kwds neg-party)])])) + (let loop ([regular-args regular-args] + [rbs rbs]) + (cond + [(null? regular-args) '()] + [(null? rbs) ((rest-ctc regular-args) neg-party)] + [else + (cons (((car rbs) (car regular-args)) neg-party) + (loop (cdr regular-args) (cdr rbs)))])))) + (define complete-blame (blame-add-missing-party blame neg-party)) + (when pre (check-pre-cond pre blame neg-party f)) + (cond + [rngs + (define results (call-with-values mk-call list)) + (define rng-len (length rngs)) + (unless (= (length results) rng-len) + (arrow:bad-number-of-results complete-blame f rng-len results)) + (when post (check-post-cond post blame neg-party f)) + (apply + values + (for/list ([result (in-list results)] + [rng (in-list rngs)]) + ((rng result) neg-party)))] + [else + (mk-call)])))) (build-populars popular-chaperone-key-table) (define (lookup-popular-chaperone-key regular-arg-count From 787500f33972aaea116a85b831436221d17790a9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 21 Aug 2015 18:53:03 -0600 Subject: [PATCH 085/381] reduce timestamp adjustments in `raco pkg create` Comments in the implementation suggest that a timestamp specialization was intended for directories, which makes sense given that directory-modification dates are not preserved when unpacking an archive. The change also affected all bytecode timestamps, however, which can create inconsistencies across package creations. --- racket/collects/pkg/private/create.rkt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/racket/collects/pkg/private/create.rkt b/racket/collects/pkg/private/create.rkt index 4efe46aa9a..ff1d6b5d51 100644 --- a/racket/collects/pkg/private/create.rkt +++ b/racket/collects/pkg/private/create.rkt @@ -47,8 +47,7 @@ ;; To make checksums more consistent, set a directory's timestamp to ;; the latest time of any of its source files. (define (use-real-timestamp? p) - (and (file-exists? p) - (regexp-match? #rx"[.](?:rkt|ss|scrbl|txt)$" p))) + (file-exists? p)) (define latest-timestamp (for/fold ([ts #f]) ([f (in-directory dir)]) (define fts (and (use-real-timestamp? f) From f63220682bc07c4704b55732c269d03a4749743a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 22 Aug 2015 07:24:17 -0600 Subject: [PATCH 086/381] add support for `compile-include-files` as an "info.rkt" field The `compile-include-files` entry lists additional files to be compiled (when their extensions do not trigger compilation). --- pkgs/racket-doc/scribblings/raco/api.scrbl | 15 ++++++++++++--- racket/collects/compiler/compiler.rkt | 5 ++++- racket/collects/setup/setup-core.rkt | 4 +++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/api.scrbl b/pkgs/racket-doc/scribblings/raco/api.scrbl index e1822669ea..e49ee75604 100644 --- a/pkgs/racket-doc/scribblings/raco/api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/api.scrbl @@ -70,6 +70,7 @@ file is reported through the current output port.} @defproc[(compile-collection-zos [collection string?] ...+ [#:skip-path skip-path (or/c path-string? #f) #f] + [#:skip-paths skip-paths (listof path-string?) null] [#:skip-doc-sources? skip-docs? any/c #f] [#:managed-compile-zo managed-compile-zo (path-string? . -> . void?) @@ -84,7 +85,7 @@ The @filepath{.zo} files are placed into the collection's By default, all files with the extension @filepath{.rkt}, @filepath{.ss}, or @filepath{.scm} in a collection are compiled, as are all such files within subdirectories, execept that -any file or directory whose path starts with @racket[skip-path] is +any file or directory whose path starts with @racket[skip-path] or an element of @racket[skip-paths] is skipped. (``Starts with'' means that the simplified path @racket[_p]'s byte-string form after @racket[(simplify-path _p #f)]starts with the byte-string form of @racket[(simplify-path skip-path #f)].) @@ -113,7 +114,7 @@ collection. The following fields are used: field's value is @racket['all].} @item{@indexed-racket[compile-omit-files] : A list of filenames (without - directory paths); that are not compiled, in addition to the + directory paths) that are not compiled, in addition to the contents of @racket[compile-omit-paths]. Do not use this field; it is for backward compatibility.} @@ -124,13 +125,21 @@ collection. The following fields are used: unless the provided @racket[skip-docs?] argument is a true value.} -]} + @item{@indexed-racket[compile-include-files] : A list of filenames (without + directory paths) to be compiled, in addition to files that + are compiled based on the file's extension, being in @racket[scribblings], + or being @racket[require]d by other compiled files.} + +] + +@history[#:changed "6.2.900.10" @elem{Added support for @racket[compile-include-files].}]} @defproc[(compile-directory-zos [path path-string?] [info ()] [#:verbose verbose? any/c #f] [#:skip-path skip-path (or/c path-string? #f) #f] + [#:skip-paths skip-paths (listof path-string?) null] [#:skip-doc-sources? skip-docs? any/c #f] [#:managed-compile-zo managed-compile-zo (path-string? . -> . void?) diff --git a/racket/collects/compiler/compiler.rkt b/racket/collects/compiler/compiler.rkt index 001b9b573e..b18800e63e 100644 --- a/racket/collects/compiler/compiler.rkt +++ b/racket/collects/compiler/compiler.rkt @@ -133,7 +133,10 @@ (if skip-docs? null (map (lambda (s) (if (string? s) (string->path s) s)) - (map car (info* 'scribblings (lambda () null))))))] + (map car (info* 'scribblings (lambda () null))))) + ;; Add specified additional sources: + (map (lambda (s) (if (string? s) (string->path s) s)) + (info* 'compile-include-files (lambda () null))))] [sses (remove* omit-paths sses)]) (worker null sses)))]) diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index 55107fb912..ad384af12e 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -546,7 +546,9 @@ (map (lambda (s) (if (string? s) (string->path s) s)) (map car (call-info info 'scribblings (lambda () null) (lambda (x) #f))))) - null))) + null) + (map (lambda (s) (if (string? s) (string->path s) s)) + (call-info info 'compile-include-files (lambda () null) void)))) (list cc srcs children-ccs)) (map build-collection-tree collections-to-compile)) From a135c78bafe59df823f8823c0728a89b1cc12f41 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 22 Aug 2015 09:25:31 -0600 Subject: [PATCH 087/381] add `module-suffixes` and `doc-module-suffixes` to "info.rkt" A `module-suffixes` entry in a collection's "info.rkt" adds a file suffix that is meant to be recognized globally (i.e., in all collections) by all Racket tools. The new fields are reported by `compiler/module-suffix` library, which is (so far) used by `raco setup`. Note that if package A includes files with a suffix that is registered by package B, then A should have a dependency on B, but `raco setup` cannot currently detect that such a dependency is needed. That dependency is likely to happen, anyway, since package A is likely using libraries form package B. --- pkgs/racket-doc/dynext/dynext.scrbl | 9 +- pkgs/racket-doc/scribblings/raco/api.scrbl | 78 +++++++++++++++- pkgs/racket-doc/scribblings/raco/setup.scrbl | 8 ++ racket/collects/compiler/compiler.rkt | 30 +++--- racket/collects/compiler/module-suffix.rkt | 58 ++++++++++++ racket/collects/dynext/file.rkt | 97 ++++++++++++-------- racket/collects/setup/getinfo.rkt | 2 +- racket/collects/setup/setup-core.rkt | 26 ++++-- 8 files changed, 243 insertions(+), 65 deletions(-) create mode 100644 racket/collects/compiler/module-suffix.rkt diff --git a/pkgs/racket-doc/dynext/dynext.scrbl b/pkgs/racket-doc/dynext/dynext.scrbl index 75a7473eda..867278d58d 100644 --- a/pkgs/racket-doc/dynext/dynext.scrbl +++ b/pkgs/racket-doc/dynext/dynext.scrbl @@ -9,7 +9,8 @@ dynext/link-unit dynext/link-sig dynext/file-unit - dynext/file-sig)) + dynext/file-sig + compiler/module-suffix)) @title{Dynext: Running a C Compiler/Linker} @@ -359,7 +360,11 @@ Appends the platform-standard dynamic-extension file suffix to (or/c path? false/c)]{ Strips the Racket file suffix from @racket[s] and returns a stripped -path. Unlike the other functions below, when @racket[program] is not +path. The recognized suffixes are the ones reported by +@racket[(get-module-suffixes #:group 'libs)] when +@racket[extract-base-filename/ss] is first called. + +Unlike the other functions below, when @racket[program] is not @racket[#f], then any suffix (including no suffix) is allowed. If @racket[s] is not a Racket file and @racket[program] is @racket[#f], @racket[#f] is returned.} diff --git a/pkgs/racket-doc/scribblings/raco/api.scrbl b/pkgs/racket-doc/scribblings/raco/api.scrbl index e49ee75604..72db5fbe6b 100644 --- a/pkgs/racket-doc/scribblings/raco/api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/api.scrbl @@ -2,6 +2,7 @@ @(require scribble/manual scribble/bnf + "common.rkt" (for-label scheme/gui compiler/compiler compiler/sig @@ -12,7 +13,9 @@ dynext/compile-sig dynext/link-sig dynext/file-sig - launcher/launcher)) + launcher/launcher + compiler/module-suffix + setup/getinfo)) @title{API for Raw Compilation} @@ -84,7 +87,9 @@ The @filepath{.zo} files are placed into the collection's By default, all files with the extension @filepath{.rkt}, @filepath{.ss}, or @filepath{.scm} in a collection are -compiled, as are all such files within subdirectories, execept that +compiled, as are all such files within subdirectories; the set of such suffixes +is extensible globally as described in @racket[get-module-suffixes], and +@racket[compile-collection-zos] recognizes suffixes from the @racket['libs] group. However, any file or directory whose path starts with @racket[skip-path] or an element of @racket[skip-paths] is skipped. (``Starts with'' means that the simplified path @racket[_p]'s byte-string form after @racket[(simplify-path _p #f)]starts with the @@ -121,15 +126,16 @@ collection. The following fields are used: @item{@indexed-racket[scribblings] : A list of pairs, each of which starts with a path for documentation source. The sources (and the files that they require) are compiled in the same way as - @filepath{.rkt}, @filepath{.ss}, and @filepath{.scm} files, - unless the provided @racket[skip-docs?] argument is a true - value.} + other module files, unless @racket[skip-docs?] is a true value.} @item{@indexed-racket[compile-include-files] : A list of filenames (without directory paths) to be compiled, in addition to files that are compiled based on the file's extension, being in @racket[scribblings], or being @racket[require]d by other compiled files.} + @item{@racket[module-suffixes] and @racket[doc-module-suffixes] --- + Used indirectly via @racket[get-module-suffixes].} + ] @history[#:changed "6.2.900.10" @elem{Added support for @racket[compile-include-files].}]} @@ -151,6 +157,68 @@ rather than a collection. The @racket[info] function behaves like the result of @racket[get-info] to supply @filepath{info.rkt} fields, instead of using an @filepath{info.rkt} file (if any) in the directory.} +@; ---------------------------------------------------------------------- + +@section[#:tag "module-suffix"]{Recognizing Module Suffixes} + +@defmodule[compiler/module-suffix]{The +@racketmodname[compiler/module-suffix] library provides functions for +recognizing file suffixes that correspond to Racket modules for the +purposes of compiling files in a directory, running tests for files in +a directory, and so on. The set of suffixes always includes +@filepath{.rkt}, @filepath{.ss}, and @filepath{.scm}, but it can be +extended globally by @filepath{info.rkt} configuration in collections.} + +@history[#:added "6.2.900.10"] + +@defproc[(get-module-suffixes [#:group group (or/c 'all 'libs 'docs) 'all] + [#:mode mode (or/c 'preferred 'all-available 'no-planet 'no-user) 'preferred] + [#:namespace namespace (or/c #f namespace?) #f]) + (listof bytes?)]{ + +Inspects @filepath{info.rkt} files (see @secref["info.rkt"]) of +installed collections to produce a list of file suffixes that should +be recognized as Racket modules. Each suffix is reported as a byte +string that does not include the @litchar{.} that precedes a suffix. + +The @racket[mode] and @racket[namespace] arguments are propagated to +@racket[find-relevant-directories] to determine which collection +directories might configure the set of suffixes. Consequently, suffix +registrations are found reliably only if @exec{raco setup} (or package +installations or updates that trigger @exec{raco setup}) is run. + +The @racket[group] argument determines whether the result includes all +registered suffixes, only those that are registered as general library +suffixes, or only those that are registered as documentation suffixes. +The set of general-library suffixes always includes @filepath{.rkt}, +@filepath{.ss}, and @filepath{.scm}. The set of documentation suffixes +always includes @filepath{.scrbl}. + +The following fields in an @filepath{info.rkt} file extend the set of +suffixes: + +@itemize[ + + @item{@indexed-racket[module-suffixes] : A list of byte strings that + correspond to general-library module suffixes (without the + @litchar{.} that must appear before the suffix). Non-lists or + non-byte-string elements of the list are ignored.} + + @item{@indexed-racket[doc-module-suffixes] : A list of byte strings + as for @racket[module-suffixes], but for documentation + modules.} + +]} + +@defproc[(get-module-suffix-regexp [#:group group (or/c 'all 'libs 'docs) 'all] + [#:mode mode (or/c 'preferred 'all-available 'no-planet 'no-user) 'preferred] + [#:namespace namespace (or/c #f namespace?) #f]) + byte-regexp?]{ + +Returns a @tech[#:doc reference-doc]{regexp value} that matches paths ending +with a suffix as reported by @racket[get-module-path-suffixes].} + + @; ---------------------------------------------------------------------- @section[#:tag "api:loading"]{Loading Compiler Support} diff --git a/pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-doc/scribblings/raco/setup.scrbl index a36829bbcb..e2a3f2b833 100644 --- a/pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -22,6 +22,7 @@ setup/unpack setup/link compiler/compiler + compiler/module-suffix launcher/launcher compiler/sig launcher/launcher-sig @@ -759,6 +760,13 @@ Optional @filepath{info.rkt} fields trigger additional actions by file, etc. Supplying a specific list of collections to @exec{raco setup} disables this dependency-based deletion of compiled files.} + @item{@racket[compile-omit-paths], @racket[compile-omit-files], and + @racket[compile-include-files] --- Used indirectly via + @racket[compile-collection-zos].} + +@item{@racket[module-suffixes] and @racket[doc-module-suffixes] --- + Used indirectly via @racket[get-module-suffixes].} + ] @; ------------------------------------------------------------------------ diff --git a/racket/collects/compiler/compiler.rkt b/racket/collects/compiler/compiler.rkt index b18800e63e..d6728b5e07 100644 --- a/racket/collects/compiler/compiler.rkt +++ b/racket/collects/compiler/compiler.rkt @@ -90,10 +90,11 @@ (compile-to-zo f zo n prefix verbose? mod?))))) (define (compile-directory-visitor dir info worker omit-root - #:verbose [verbose? #t] - #:skip-path [orig-skip-path #f] - #:skip-paths [orig-skip-paths null] - #:skip-doc-sources? [skip-docs? #f]) + #:verbose verbose? + #:has-module-suffix? has-module-suffix? + #:skip-path orig-skip-path + #:skip-paths orig-skip-paths + #:skip-doc-sources? skip-docs?) (define info* (or info (lambda (key mk-default) (mk-default)))) (define omit-paths (omitted-paths dir c-get-info/full omit-root)) (define skip-paths (for/list ([p (in-list (if orig-skip-path @@ -128,7 +129,7 @@ (cons -inf.0 "")))))))))]) (let* ([sses (append ;; Find all .rkt/.ss/.scm files: - (filter extract-base-filename/ss (directory-list)) + (filter has-module-suffix? (directory-list)) ;; Add specified doc sources: (if skip-docs? null @@ -155,8 +156,9 @@ #:skip-doc-sources? skip-docs?) init)))) init)))) - (define (compile-directory dir info - #:verbose [verbose? #t] + (define (compile-directory dir info + #:has-module-suffix? [has-module-suffix? extract-base-filename/ss] + #:verbose [verbose? #t] #:skip-path [orig-skip-path #f] #:skip-paths [orig-skip-paths null] #:skip-doc-sources? [skip-docs? #f] @@ -166,29 +168,30 @@ (define (worker prev sses) (for-each managed-compile-zo sses)) (compile-directory-visitor dir info worker omit-root + #:has-module-suffix? has-module-suffix? #:verbose verbose? #:skip-path orig-skip-path #:skip-paths orig-skip-paths #:skip-doc-sources? skip-docs?)) - (define (get-compile-directory-srcs dir info + (define (get-compile-directory-srcs dir info + #:has-module-suffix? [has-module-suffix? extract-base-filename/ss] #:verbose [verbose? #t] #:skip-path [orig-skip-path #f] #:skip-paths [orig-skip-paths null] #:skip-doc-sources? [skip-docs? #f] - #:managed-compile-zo [managed-compile-zo - (make-caching-managed-compile-zo)] #:omit-root [omit-root dir]) (compile-directory-visitor dir info append omit-root + #:has-module-suffix? has-module-suffix? #:verbose verbose? #:skip-path orig-skip-path #:skip-paths orig-skip-paths - #:skip-doc-sources? skip-docs? - #:managed-compile-zo managed-compile-zo)) + #:skip-doc-sources? skip-docs?)) (define unspec (gensym)) - (define (compile-collection-zos collection + (define (compile-collection-zos collection + #:has-module-suffix? [has-module-suffix? extract-base-filename/ss] #:skip-path [skip-path #f] #:skip-paths [skip-paths null] #:skip-doc-sources? [skip-docs? #f] @@ -202,6 +205,7 @@ #:omit-root (if (eq? omit-root unspec) dir omit-root) + #:has-module-suffix? has-module-suffix? #:verbose #f #:skip-path skip-path #:skip-paths skip-paths diff --git a/racket/collects/compiler/module-suffix.rkt b/racket/collects/compiler/module-suffix.rkt new file mode 100644 index 0000000000..f600ef7967 --- /dev/null +++ b/racket/collects/compiler/module-suffix.rkt @@ -0,0 +1,58 @@ +#lang racket/base +(require racket/list + racket/string + setup/getinfo + racket/contract/base) + +(provide + (contract-out + [get-module-suffixes (() + (#:mode (or/c 'preferred 'all-available 'no-planet 'no-user) + #:group (or/c 'all 'libs 'docs) + #:namespace (or/c #f namespace?)) + . ->* . + (listof bytes?))] + [get-module-suffix-regexp (() + (#:mode (or/c 'preferred 'all-available 'no-planet 'no-user) + #:group (or/c 'all 'libs 'docs) + #:namespace (or/c #f namespace?)) + . ->* . + byte-regexp?)])) + +(define (get-module-suffixes #:mode [key 'preferred] + #:group [group 'all] + #:namespace [namespace #f]) + (define fields (case group + [(all) '(module-suffixes doc-module-suffixes)] + [(libs) '(module-suffixes)] + [(docs) '(doc-module-suffixes)])) + (define dirs (find-relevant-directories fields key)) + (define rkt-ht (if (memq 'module-suffixes fields) + (hash #"rkt" #t #"ss" #t #"scm" #t) + (hash))) + (define init-ht (if (memq 'doc-module-suffixes fields) + (hash-set rkt-ht #"scrbl" #t) + rkt-ht)) + (define ht + (for/fold ([ht init-ht]) ([dir (in-list dirs)]) + (define info (get-info/full dir #:namespace namespace)) + (for/fold ([ht init-ht]) ([field (in-list fields)]) + (define suffixes (info field (lambda () null))) + (cond + [(list? suffixes) + (for/fold ([ht ht]) ([suffix (in-list suffixes)]) + (cond + [(bytes? suffix) (hash-set ht suffix #t)] + [else ht]))])))) + (sort (hash-keys ht) bytesbytes (appender (bytes->path #"x"))) 1)) -(define-values (extract-base-filename/ss - extract-base-filename/c - extract-base-filename/kp - extract-base-filename/o - extract-base-filename/ext) - (let ([mk - (lambda (who pat kind simple) - (define (extract-base-filename s [p #f]) - (define rx - (byte-pregexp (bytes-append #"^(.*)\\.(?i:" pat #")$"))) - (unless (path-string? s) - (raise-type-error who "path or valid-path string" s)) - (cond [(regexp-match - rx (path->bytes (if (path? s) s (string->path s)))) - => (lambda (m) (bytes->path (cadr m)))] - [p (if simple - (error p "not a ~a filename (doesn't end with ~a): ~a" - kind simple s) - (path-replace-suffix s #""))] - [else #f])) - extract-base-filename)]) - (values - (mk 'extract-base-filename/ss #"rkt|ss|scm" "Racket" #f) - (mk 'extract-base-filename/c - #"c|cc|cxx|cpp|c[+][+]|m" "C" ".c, .cc, .cxx, .cpp, .c++, or .m") - (mk 'extract-base-filename/kp #"kp" "constant pool" ".kp") - (mk 'extract-base-filename/o - (case (system-type) - [(unix beos macos macosx) #"o"] - [(windows) #"obj"]) - "compiled object" - (extract-suffix append-object-suffix)) - (mk 'extract-base-filename/ext - (regexp-quote (subbytes (system-type 'so-suffix) 1) #f) - "Racket extension" - (extract-suffix append-extension-suffix))))) +(define (extract-rx pat) + (byte-pregexp (bytes-append #"^(.*)\\.(?i:" pat #")$"))) + +(define (extract who s program rx kind simple) + (unless (path-string? s) + (raise-argument-error who "path-string?" s)) + (cond + [(regexp-match rx (if (path? s) s (string->path s))) + => (lambda (m) (bytes->path (cadr m)))] + [program + (if simple + (error program "not a ~a filename (doesn't end with ~a): ~a" + kind simple s) + (path-replace-suffix s #""))] + [else #f])) + +(define module-suffix-regexp + (delay (get-module-suffix-regexp #:group 'libs))) + +(define (extract-base-filename/ss s [program #f] + #:module-pattern [module-pattern + (force module-suffix-regexp)]) + (extract 'extract-base-filename/ss + s program + module-pattern + "Racket" + #f)) + +(define (extract-base-filename/c s [program #f]) + (extract 'extract-base-filename/c + s program + (extract-rx #"c|cc|cxx|cpp|c[+][+]|m") + "C" + ".c, .cc, .cxx, .cpp, .c++, or .m")) + +(define (extract-base-filename/kp s [program #f]) + (extract 'extract-base-filename/kp + s + program + (extract-rx #"kp") + "constant pool" + ".kp")) + +(define (extract-base-filename/o s [program #f]) + (extract 'extract-base-filename/o + s program + (case (system-type) + [(unix beos macos macosx) #"o"] + [(windows) #"obj"]) + "compiled object" + (extract-suffix append-object-suffix))) + +(define (extract-base-filename/ext s [program #f]) + (extract 'extract-base-filename/ext + s + program + (regexp-quote (subbytes (system-type 'so-suffix) 1) #f) + "Racket extension" + (extract-suffix append-extension-suffix))) diff --git a/racket/collects/setup/getinfo.rkt b/racket/collects/setup/getinfo.rkt index a29c9530f8..0c81b0e0cb 100644 --- a/racket/collects/setup/getinfo.rkt +++ b/racket/collects/setup/getinfo.rkt @@ -1,7 +1,7 @@ #lang racket/base (require racket/match - racket/contract + racket/contract/base planet/cachepath syntax/modread "dirs.rkt" diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index ad384af12e..12303c5342 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -20,7 +20,7 @@ compiler/compiler (prefix-in compiler:option: compiler/option) launcher/launcher - dynext/file + compiler/module-suffix "unpack.rkt" "getinfo.rkt" @@ -508,7 +508,7 @@ (let loop ([l collections-to-compile]) (append-map (lambda (cc) (cons cc (loop (get-subs cc)))) l)))) - (define (collection-tree-map collections-to-compile) + (define (collection-tree-map collections-to-compile has-module-suffix?) (define (build-collection-tree cc) (define (make-child-cc parent-cc name) (collection-cc! (append (cc-collection parent-cc) (list name)) @@ -540,7 +540,7 @@ (filter-map (lambda (x) (make-child-cc cc x)) dirs))) (define srcs (append - (filter extract-base-filename/ss files) + (filter has-module-suffix? files) (if make-docs? (filter (lambda (p) (not (member p omit))) (map (lambda (s) (if (string? s) (string->path s) s)) @@ -984,7 +984,7 @@ ;; and it makes a do-nothing setup complete much faster. (define caching-managed-compile-zo (make-caching-managed-compile-zo)) - (define (compile-cc cc gcs) + (define (compile-cc cc gcs has-module-suffix?) (parameterize ([current-namespace (make-base-empty-namespace)]) (begin-record-error cc "making" (setup-printf "making" "~a" (cc-name cc)) @@ -999,6 +999,7 @@ (define dir (cc-path cc)) (define info (cc-info cc)) (compile-directory-zos dir info + #:has-module-suffix? has-module-suffix? #:omit-root (cc-omit-root cc) #:managed-compile-zo caching-managed-compile-zo #:skip-path (and (avoid-main-installation) main-collects-dir) @@ -1025,6 +1026,14 @@ (case where [(beginning) (append same diff)] [(end) (append diff same)]))) + (define has-module-suffix? + (let ([rx (get-module-suffix-regexp + #:mode (cond + [(make-user) 'preferred] + [else 'no-user]) + #:group 'libs + #:namespace info-ns)]) + (lambda (p) (regexp-match? rx p)))) (setup-printf #f "--- compiling collections ---") (if ((parallel-workers) . > . 1) (begin @@ -1034,24 +1043,25 @@ (when (and (cc-main? cc) (member (cc-info-root cc) (current-library-collection-paths))) - (compile-cc cc 0)))) + (compile-cc cc 0 has-module-suffix?)))) (with-specified-mode (lambda () (define cct (move-to 'beginning (list #rx"/compiler$" #rx"/raco$" #rx"/racket$" #rx"/images/") (move-to 'end (list #rx"/drracket") (sort-collections-tree - (collection-tree-map top-level-plt-collects))))) + (collection-tree-map top-level-plt-collects + has-module-suffix?))))) (iterate-cct clean-cc cct) (parallel-compile (parallel-workers) setup-fprintf handle-error cct) (for/fold ([gcs 0]) ([cc planet-dirs-to-compile]) - (compile-cc cc gcs))))) + (compile-cc cc gcs has-module-suffix?))))) (with-specified-mode (lambda () (for ([cc ccs-to-compile]) (clean-cc cc)) (for/fold ([gcs 0]) ([cc ccs-to-compile]) - (compile-cc cc gcs)))))) + (compile-cc cc gcs has-module-suffix?)))))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Info-Domain Cache ;; From 66df8a2b9f828575389f2abc31f29f004faf025b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 22 Aug 2015 09:42:56 -0600 Subject: [PATCH 088/381] document `raco test` conversion to `get-module-suffixes` --- pkgs/racket-doc/scribblings/raco/test.scrbl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/test.scrbl b/pkgs/racket-doc/scribblings/raco/test.scrbl index 2c2c9fffd4..cd4e0a4a94 100644 --- a/pkgs/racket-doc/scribblings/raco/test.scrbl +++ b/pkgs/racket-doc/scribblings/raco/test.scrbl @@ -5,7 +5,8 @@ (for-label racket/runtime-path racket/base launcher/launcher - rackunit/log)) + rackunit/log + compiler/module-suffix)) @title[#:tag "test"]{@exec{raco test}: Run tests} @@ -19,8 +20,9 @@ the file. When an argument path refers to a directory, @exec{raco test} recursively discovers and runs all files within the directory that end -in @filepath{.rkt}, end in @filepath{.scrbl}, or have a (possibly -empty) list of command-line arguments provided by +in a module suffix (see @racket[get-module-suffixes], but the suffixes +always include @filepath{.rkt}, @filepath{.scrbl}, @filepath{.ss}, and +@filepath{.scm}) or have a (possibly empty) list of command-line arguments provided by @racket[test-command-line-arguments] in an @filepath{info.rkt} file, or as directed by @racket[test-include-paths] in an @filepath{info.rkt} file. At the same time, @exec{raco test} omits @@ -53,8 +55,7 @@ The @exec{raco test} command accepts several flags: --- Not only interprets the arguments as paths (which is the default mode), but treats them the same as paths found in a directory, which means ignoring a file argument that does not - have the extension @filepath{.rkt}, does not have the extension - @filepath{.scrbl}, or is not enabled explicitly via + have a module extension or is not enabled explicitly via @racket[test-command-line-arguments] or @racket[test-include-paths] in an @filepath{info.rkt} file; meanwhile, paths that are otherwise enabled can be disabled via @racket[test-omit-paths] in an @@ -153,7 +154,9 @@ The @exec{raco test} command accepts several flags: ] -@history[#:changed "1.1" @elem{Added @DFlag{heartbeat}.}] +@history[#:changed "1.1" @elem{Added @DFlag{heartbeat}.} + #:changed "1.4" @elem{Changed recognition of module suffixes to use @racket[get-module-suffixes], + which implies recognizing @filepath{.ss} and @filepath{.rkt}.}] @section[#:tag "test-config"]{Test Configuration by Submodule} @@ -265,6 +268,9 @@ The following @filepath{info.rkt} fields are recognized: the enclosing directory) for modules whose output varies. See @secref["test-responsible"].} + @item{@racket[module-suffixes] and @racket[doc-module-suffixes] --- + Used indirectly via @racket[get-module-suffixes].} + ] @section[#:tag "test-responsible"]{Responsible-Party and Varying-Output Logging} From 70ab4cfb12840262be4fa517a216aea265cef9be Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 22 Aug 2015 19:33:57 -0400 Subject: [PATCH 089/381] fix date*->seconds handling of nanoseconds field --- pkgs/racket-test-core/tests/racket/date.rktl | 6 +++++- racket/collects/racket/date.rkt | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/date.rktl b/pkgs/racket-test-core/tests/racket/date.rktl index 082a040f37..55b9d0f24e 100644 --- a/pkgs/racket-test-core/tests/racket/date.rktl +++ b/pkgs/racket-test-core/tests/racket/date.rktl @@ -43,7 +43,7 @@ (date-day d) (date-month d) (date-year d) (date-week-day d) (date-year-day d) (date-dst? d) (date-time-zone-offset d) - 62500 + 62500000 "MDT")]) (define (test-string fmt time? result) (test (parameterize ([date-display-format fmt]) @@ -113,4 +113,8 @@ (struct-copy date* (seconds->date (current-seconds)) [hour #:parent date 5])) +(let ([d ;; 2015-08-22T12:34:56.789000000Z + (date* 56 34 12 22 08 2015 6 233 #f 0 789000000 "UTC")]) + (test 789/1000 - (date*->seconds d) (date->seconds d))) + (report-errs) diff --git a/racket/collects/racket/date.rkt b/racket/collects/racket/date.rkt index f7dc2606ba..4aada9f0e9 100644 --- a/racket/collects/racket/date.rkt +++ b/racket/collects/racket/date.rkt @@ -242,7 +242,7 @@ (define (date*->seconds date [local-time? #t]) (define s (date->seconds date local-time?)) (if (date*? date) - (+ s (/ (date*-nanosecond date) 1000000)) + (+ s (/ (date*-nanosecond date) #e1e9)) s)) (define (find-seconds sec min hour day month year [local-time? #t]) From 0c31a0c0b81ccb3b965e4573cdb6fa39d03f383c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 22 Aug 2015 20:19:06 -0500 Subject: [PATCH 090/381] add some missing contract profiler wcm expressions and start a test suite for them --- .../tests/racket/contract/prof.rkt | 102 ++++++++++++++++++ .../contract/private/arrow-higher-order.rkt | 20 ++-- .../contract/private/arrow-val-first.rkt | 87 ++++++++++----- .../collects/racket/contract/private/misc.rkt | 18 +++- 4 files changed, 189 insertions(+), 38 deletions(-) create mode 100644 pkgs/racket-test/tests/racket/contract/prof.rkt diff --git a/pkgs/racket-test/tests/racket/contract/prof.rkt b/pkgs/racket-test/tests/racket/contract/prof.rkt new file mode 100644 index 0000000000..c6ff702575 --- /dev/null +++ b/pkgs/racket-test/tests/racket/contract/prof.rkt @@ -0,0 +1,102 @@ +#lang racket/base +(require "test-util.rkt") + +(parameterize ([current-contract-namespace + (make-basic-contract-namespace + 'racket/contract)]) + + (contract-eval + '(module prof-fun racket/base + (require (only-in racket/contract/private/guts + contract-continuation-mark-key) + (only-in racket/contract/private/blame + blame-positive + blame-negative + blame?)) + (provide pos-blame? neg-blame? named-blame?) + (define (named-blame? who) + (define mark-info + (continuation-mark-set-first + (current-continuation-marks) + contract-continuation-mark-key)) + (define (get-party selector) + (and mark-info + (or (selector (car mark-info)) + (cdr mark-info)))) + (and mark-info + (let ([pos (get-party blame-positive)] + [neg (get-party blame-negative)]) + (or (equal? pos who) + (equal? neg who))))) + (define (pos-blame? _) (named-blame? 'pos)) + (define (neg-blame? _) (named-blame? 'neg)))) + + (contract-eval '(require 'prof-fun)) + + (test/spec-passed + 'provide/contract1 + '((contract (-> neg-blame? any/c) (λ (x) x) 'pos 'neg) 1)) + + (test/spec-passed + 'provide/contract2 + '((contract (-> any/c pos-blame?) (λ (x) x) 'pos 'neg) 1)) + + (test/spec-passed + 'provide/contract3 + '(contract (vector/c pos-blame?) (vector 1) 'pos 'neg)) + + (test/spec-passed + 'provide/contract4 + '((contract (parameter/c pos-blame?) (make-parameter #f) 'pos 'neg))) + + (test/spec-passed + 'provide/contract5 + '(contract (unconstrained-domain-> pos-blame?) (λ () 1) 'pos 'neg)) + + (test/spec-passed + 'provide/contract6 + '(contract (->* () #:pre neg-blame? any) (λ () 1) 'pos 'neg)) + + (test/spec-passed + 'provide/contract7 + '(contract (->* () any/c #:post pos-blame?) (λ () 1) 'pos 'neg)) + + (test/spec-passed/result + 'provide/contract8 + '(let () + (eval '(module prof1 racket/base + (require racket/contract 'prof-fun) + (define (f x) x) + (define a-contract (-> (λ _ (named-blame? 'prof1)) any/c)) + (provide + (contract-out + [f a-contract])))) + (eval '(require 'prof1)) + (eval '(f 11))) + 11) + + (test/spec-passed/result + 'provide/contract9 + '(let () + (eval '(module prof2 racket/base + (require racket/contract 'prof-fun) + (define (f x) x) + (provide + (contract-out + [f (-> (λ _ (named-blame? 'prof2)) any/c)])))) + (eval '(require 'prof2)) + (eval '(f 11))) + 11) + + (test/spec-passed/result + 'provide/contract10 + '(let () + (eval '(module prof3 racket/base + (require racket/contract 'prof-fun) + (define (f #:x x) x) + (provide + (contract-out + [f (-> #:x (λ _ (named-blame? 'prof3)) any/c)])))) + (eval '(require 'prof3)) + (eval '(f #:x 11))) + 11)) diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index 28e82fc5d6..20a2eade0e 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -59,16 +59,20 @@ (define (check-pre-cond pre blame neg-party val) - (unless (pre) - (raise-blame-error (blame-swap blame) - #:missing-party neg-party - val "#:pre condition"))) + (with-continuation-mark contract-continuation-mark-key + (cons blame neg-party) + (unless (pre) + (raise-blame-error (blame-swap blame) + #:missing-party neg-party + val "#:pre condition")))) (define (check-post-cond post blame neg-party val) - (unless (post) - (raise-blame-error blame - #:missing-party neg-party - val "#:post condition"))) + (with-continuation-mark contract-continuation-mark-key + (cons blame neg-party) + (unless (post) + (raise-blame-error blame + #:missing-party neg-party + val "#:post condition")))) (define (check-pre-cond/desc post blame neg-party val) (handle-pre-post/desc-string #t post blame neg-party val)) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 46c3d4208b..fb9a26aad4 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -179,19 +179,30 @@ [(arg-x ...) (generate-temporaries regular-args)] [(res-x ...) (generate-temporaries (or rngs '()))] [(kwd-arg-x ...) (generate-temporaries mandatory-kwds)]) - + + (define base-arg-expressions (reverse (syntax->list #'(((regb arg-x) neg-party) ...)))) + (define normal-arg-vars (generate-temporaries #'(arg-x ...))) + (define base-arg-vars normal-arg-vars) + (with-syntax ([(formal-kwd-args ...) (apply append (map list mandatory-kwds (syntax->list #'(kwd-arg-x ...))))] [(kwd-arg-exps ...) - (apply append (map (λ (kwd kwd-arg-x kb) - (list kwd #`((#,kb #,kwd-arg-x) neg-party))) - mandatory-kwds - (syntax->list #'(kwd-arg-x ...)) - (syntax->list #'(kb ...))))] + (apply + append + (map (λ (kwd kwd-arg-x kb) + (set! base-arg-expressions + (cons #`((#,kb #,kwd-arg-x) neg-party) + base-arg-expressions)) + (set! base-arg-vars (cons (car (generate-temporaries (list kwd-arg-x))) + base-arg-vars)) + (list kwd (car base-arg-vars))) + mandatory-kwds + (syntax->list #'(kwd-arg-x ...)) + (syntax->list #'(kb ...))))] [(letrec-bound-id) (generate-temporaries '(f))]) (with-syntax ([(wrapper-args ...) #'(neg-party arg-x ... formal-kwd-args ...)] - [(the-call ...) #'(f ((regb arg-x) neg-party) ... kwd-arg-exps ...)] + [(the-call ...) #`(f #,@(reverse normal-arg-vars) kwd-arg-exps ...)] [(pre-check ...) (if pre (list #`(check-pre-cond #,pre blame neg-party f)) @@ -211,46 +222,70 @@ (let loop ([optional-args (reverse optional-args)] [ob (reverse (syntax->list #'(optb ...)))] [first? #t]) + (define args-expressions base-arg-expressions) + (define args-vars base-arg-vars) (define no-rest-call - #`(the-call ... #,@(for/list ([ob (in-list (reverse ob))] - [optional-arg (in-list (reverse optional-args))]) - #`((#,ob #,optional-arg) neg-party)))) + #`(the-call ... + #,@(for/list ([ob (in-list (reverse ob))] + [optional-arg (in-list (reverse optional-args))]) + (set! args-expressions + (cons #`((#,ob #,optional-arg) neg-party) + args-expressions)) + (set! args-vars + (cons (car (generate-temporaries (list optional-arg))) + args-vars)) + (car args-vars)))) (define full-call - (if (and first? rest) - #`(apply #,@no-rest-call ((restb rest-arg) neg-party)) - no-rest-call)) + (cond + [(and first? rest) + (set! args-expressions (cons #'((restb rest-arg) neg-party) args-expressions)) + (set! args-vars (cons (car (generate-temporaries '(rest-args-arrow-contract))) + args-vars)) + #`(apply #,@no-rest-call #,(car args-vars))] + [else + no-rest-call])) (define the-args #`(wrapper-args ... #,@(reverse optional-args) #,@(if (and first? rest) #'rest-arg '()))) + (define let-values-clause + #`[#,(reverse args-vars) + (with-continuation-mark contract-continuation-mark-key + (cons blame neg-party) + (values #,@(reverse args-expressions)))]) + (define the-clause (if rngs #`[#,the-args pre-check ... (define-values (failed res-x ...) (call-with-values - (λ () #,full-call) + (λ () (let-values (#,let-values-clause) + #,full-call)) (case-lambda [(res-x ...) (values #f res-x ...)] [args (values args #,@(map (λ (x) #'#f) (syntax->list #'(res-x ...))))]))) - (cond - [failed - (wrong-number-of-results-blame - blame neg-party f - failed - #,(length - (syntax->list - #'(res-x ...))))] - [else - post-check ... - (values ((rb res-x) neg-party) ...)])] + (with-continuation-mark contract-continuation-mark-key + (cons blame neg-party) + (cond + [failed + (wrong-number-of-results-blame + blame neg-party f + failed + #,(length + (syntax->list + #'(res-x ...))))] + [else + post-check ... + (values ((rb res-x) neg-party) ...)]))] #`[#,the-args pre-check ... - #,full-call])) + (let-values (#,let-values-clause) + #,full-call)])) (cons the-clause (cond [(null? optional-args) '()] diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index e6bbf9591a..e79536ff73 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -1493,8 +1493,13 @@ [out-proc (contract-projection (parameter/c-out ctc))]) (λ (blame) (define blame/c (blame-add-context blame "the parameter of")) - (define partial-neg-contract (in-proc (blame-swap blame/c))) - (define partial-pos-contract (out-proc blame/c)) + (define (add-profiling f) + (λ (x) + (with-continuation-mark contract-continuation-mark-key + (cons blame #f) + (f x)))) + (define partial-neg-contract (add-profiling (in-proc (blame-swap blame/c)))) + (define partial-pos-contract (add-profiling (out-proc blame/c))) (λ (val) (cond [(parameter? val) @@ -1515,11 +1520,16 @@ (cond [(parameter? val) (λ (neg-party) + (define (add-profiling f) + (λ (x) + (with-continuation-mark contract-continuation-mark-key + (cons blame neg-party) + (f x)))) (make-derived-parameter val ;; unfortunately expensive - (in-proc (blame-add-missing-party swapped neg-party)) - (out-proc (blame-add-missing-party blame/c neg-party))))] + (add-profiling (in-proc (blame-add-missing-party swapped neg-party))) + (add-profiling (out-proc (blame-add-missing-party blame/c neg-party)))))] [else (λ (neg-party) (raise-blame-error blame #:missing-party neg-party From 49c4d9272fe081f6d91fcab7e59d9333fb524091 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 23 Aug 2015 10:58:04 -0600 Subject: [PATCH 091/381] change `let/cc` and `let/ec` macros back to `call/cc` and `call/ec` When `call/cc` and `call/ec` were moved out of `#%kernel`, the `let/cc` and `let/ec` macros changed to refer to `call-with-current-continuation` and `call-with-escape-continuation`. Move `call/cc` and `call/ec` again and restore the macros, so that matching on the expansion of the macros (e.g,. in the web server's language that looks for `call/cc`) work as before. --- racket/collects/racket/private/define-et-al.rkt | 6 ++++-- racket/collects/racket/private/more-scheme.rkt | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/racket/collects/racket/private/define-et-al.rkt b/racket/collects/racket/private/define-et-al.rkt index fea6207fc0..4f617c9d79 100644 --- a/racket/collects/racket/private/define-et-al.rkt +++ b/racket/collects/racket/private/define-et-al.rkt @@ -71,6 +71,8 @@ "bad syntax" x))))) + (define-values (call/ec) call-with-escape-continuation) + (-define-syntax let/ec (lambda (code) (let ([l (syntax->list code)]) @@ -81,7 +83,7 @@ [exprs (stx-cdr (stx-cdr code))]) (datum->syntax (quote-syntax here) - `(call-with-escape-continuation (lambda (,var) ,@(stx->list exprs))) + `(call/ec (lambda (,var) ,@(stx->list exprs))) code)) (raise-syntax-error #f @@ -198,4 +200,4 @@ (syntax-local-introduce super-id)) result)))))))))) - (#%provide -define -define-syntax when unless let/ec -define-struct)) + (#%provide -define -define-syntax when unless call/ec let/ec -define-struct)) diff --git a/racket/collects/racket/private/more-scheme.rkt b/racket/collects/racket/private/more-scheme.rkt index b1511ce779..8284abdd7e 100644 --- a/racket/collects/racket/private/more-scheme.rkt +++ b/racket/collects/racket/private/more-scheme.rkt @@ -300,13 +300,12 @@ (set! id temp) ...)))]))) (define-values (call/cc) call-with-current-continuation) - (define-values (call/ec) call-with-escape-continuation) (define-syntax let/cc (lambda (stx) (syntax-case stx () [(_ var body1 body ...) - (syntax/loc stx (call-with-current-continuation (lambda (var) body1 body ...)))]))) + (syntax/loc stx (call/cc (lambda (var) body1 body ...)))]))) (define-syntax fluid-let (lambda (stx) @@ -389,6 +388,6 @@ (rename break-paramz? break-parameterization?) with-handlers with-handlers* call-with-exception-handler set!-values - let/cc call/cc call/ec fluid-let time + let/cc call/cc fluid-let time log-fatal log-error log-warning log-info log-debug define-logger hash-ref! hash-has-key? hash-update hash-update!)) From b7f500fc262d858b14265ee78349c6a68758157b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 23 Aug 2015 23:14:31 -0500 Subject: [PATCH 092/381] create the blame+neg-party pair only once, not once for the domain and once for the range --- .../contract/private/arrow-val-first.rkt | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index fb9a26aad4..5ac0e6de1f 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -252,40 +252,42 @@ (define let-values-clause #`[#,(reverse args-vars) (with-continuation-mark contract-continuation-mark-key - (cons blame neg-party) + blame+neg-party (values #,@(reverse args-expressions)))]) (define the-clause (if rngs #`[#,the-args - pre-check ... - (define-values (failed res-x ...) - (call-with-values - (λ () (let-values (#,let-values-clause) - #,full-call)) - (case-lambda - [(res-x ...) - (values #f res-x ...)] - [args - (values args #,@(map (λ (x) #'#f) - (syntax->list #'(res-x ...))))]))) - (with-continuation-mark contract-continuation-mark-key - (cons blame neg-party) - (cond - [failed - (wrong-number-of-results-blame - blame neg-party f - failed - #,(length - (syntax->list - #'(res-x ...))))] - [else - post-check ... - (values ((rb res-x) neg-party) ...)]))] + (let ([blame+neg-party (cons blame neg-party)]) + pre-check ... + (define-values (failed res-x ...) + (call-with-values + (λ () (let-values (#,let-values-clause) + #,full-call)) + (case-lambda + [(res-x ...) + (values #f res-x ...)] + [args + (values args #,@(map (λ (x) #'#f) + (syntax->list #'(res-x ...))))]))) + (with-continuation-mark contract-continuation-mark-key + blame+neg-party + (cond + [failed + (wrong-number-of-results-blame + blame neg-party f + failed + #,(length + (syntax->list + #'(res-x ...))))] + [else + post-check ... + (values ((rb res-x) neg-party) ...)])))] #`[#,the-args pre-check ... - (let-values (#,let-values-clause) - #,full-call)])) + (let ([blame+neg-party (cons blame neg-party)]) + (let-values (#,let-values-clause) + #,full-call))])) (cons the-clause (cond [(null? optional-args) '()] From c0dac75b7df1813248a18095c66dfd233f073bd9 Mon Sep 17 00:00:00 2001 From: Leif Andersen Date: Sun, 23 Aug 2015 14:05:06 -0400 Subject: [PATCH 093/381] Fix typo in zo structs documentation: Which -> When --- pkgs/racket-doc/scribblings/raco/zo-struct.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl index c2be857a63..a400ec0dbe 100644 --- a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl +++ b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl @@ -335,7 +335,7 @@ binding, constructor, etc.} values; also, this information is redundant, since it can be inferred by the bindings referenced though @racket[closure-map]. - Which a closure captures top-level or module-level variables or + When a closure captures top-level or module-level variables or refers to a syntax-object constant, the variables and constants are represented in the closure by capturing a prefix (in the sense of @racket[prefix]). The @racket[toplevel-map] field indicates From 620ccbfa03397623aa18fee4918653739365de49 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 23 Aug 2015 17:35:34 -0600 Subject: [PATCH 094/381] JIT: streamline `values` result delivered to `let-values` In a case like (let-values ([(X ...) (with-continuation-mark M_k M_v (values M ...))]) ....) where the bytecode compiler cannot convert to a sequence of `let` bindings, make the JIT implement `values` as delivering argument results directly to the corresponding variable locations. --- racket/src/racket/src/jit.c | 227 ++++++++++++++++++++---------- racket/src/racket/src/jit.h | 10 +- racket/src/racket/src/jitarith.c | 2 +- racket/src/racket/src/jitcall.c | 8 +- racket/src/racket/src/jitinline.c | 20 +-- 5 files changed, 179 insertions(+), 88 deletions(-) diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 4cb2bd4d67..4fbfd74ef3 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -1455,9 +1455,10 @@ void scheme_generate_non_tail_mark_pos_suffix(mz_jit_state *jitter) mz_tl_sti_l(tl_scheme_current_cont_mark_pos, JIT_R2, JIT_R0); } -static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitter, - int multi_ok, int mark_pos_ends, int ignored, - Branch_Info *for_branch) +static int generate_non_tail_with_branch_and_values(Scheme_Object *obj, mz_jit_state *jitter, + int multi_ok, int mark_pos_ends, int ignored, + Branch_Info *for_branch, + Expected_Values_Info *for_values) /* de-sync's rs */ { int flostack, flostack_pos; @@ -1474,7 +1475,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte for_branch->flostack = flostack; for_branch->flostack_pos = flostack_pos; } - v = scheme_generate(obj, jitter, 0, 0, multi_ok, ignored ? -1 : JIT_R0, for_branch); + v = scheme_generate(obj, jitter, 0, 0, multi_ok, ignored ? -1 : JIT_R0, for_branch, for_values); CHECK_LIMIT(); scheme_mz_flostack_restore(jitter, flostack, flostack_pos, !for_branch, 1); FOR_LOG(--jitter->log_depth); @@ -1538,7 +1539,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte PAUSE_JIT_DATA(); FOR_LOG(jitter->log_depth++); - scheme_generate(obj, jitter, 0, 0, multi_ok, ignored ? -1 : JIT_R0, for_branch); /* no sync */ + scheme_generate(obj, jitter, 0, 0, multi_ok, ignored ? -1 : JIT_R0, for_branch, for_values); /* no sync */ FOR_LOG(--jitter->log_depth); RESUME_JIT_DATA(); @@ -1579,7 +1580,14 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte int scheme_generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int mark_pos_ends, int ignored) { - return generate_non_tail_with_branch(obj, jitter, multi_ok, mark_pos_ends, ignored, NULL); + return generate_non_tail_with_branch_and_values(obj, jitter, multi_ok, mark_pos_ends, ignored, NULL, NULL); +} + +int scheme_generate_non_tail_for_values(Scheme_Object *obj, mz_jit_state *jitter, + int multi_ok, int mark_pos_ends, int ignored, + Expected_Values_Info *for_values) +{ + return generate_non_tail_with_branch_and_values(obj, jitter, multi_ok, mark_pos_ends, ignored, NULL, for_values); } int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway) @@ -1590,14 +1598,14 @@ int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inline if (inlined_ok) { if (inlined_ok == 2) - return scheme_generate(obj, jitter, 0, 0, 1, JIT_R0, NULL); + return scheme_generate(obj, jitter, 0, 0, 1, JIT_R0, NULL, NULL); else return scheme_generate_non_tail(obj, jitter, 0, 1, 0); } else if (unbox_anyway && SAME_TYPE(SCHEME_TYPE(obj), scheme_local_type)) { /* local unboxing can be handled in generate(), and we want to handle it there to avoid unnecessary (and potentially harmful) clearing of the runstack location */ - return scheme_generate(obj, jitter, 0, 0, 1, JIT_R0, NULL); + return scheme_generate(obj, jitter, 0, 0, 1, JIT_R0, NULL, NULL); } if (!jitter->unbox || jitter->unbox_depth) @@ -1632,11 +1640,14 @@ static Scheme_Object *generate_k(void) mz_jit_state *jitter = (mz_jit_state *)p->ku.k.p2; Branch_Info *for_branch = (Branch_Info *)p->ku.k.p3, for_branch_copy; Branch_Info_Addr *for_branch_addrs = (Branch_Info_Addr *)p->ku.k.p4; + Expected_Values_Info *for_values = (Expected_Values_Info *)p->ku.k.p5; int v; p->ku.k.p1 = NULL; p->ku.k.p2 = NULL; p->ku.k.p3 = NULL; + p->ku.k.p4 = NULL; + p->ku.k.p5 = NULL; if (for_branch) { memcpy(&for_branch_copy, for_branch, sizeof(Branch_Info)); @@ -1644,7 +1655,8 @@ static Scheme_Object *generate_k(void) } v = scheme_generate(obj, jitter, p->ku.k.i1, p->ku.k.i4, p->ku.k.i2, p->ku.k.i3, - (for_branch ? &for_branch_copy : NULL)); + (for_branch ? &for_branch_copy : NULL), + for_values); if (for_branch) { memcpy(for_branch, &for_branch_copy, sizeof(Branch_Info)); @@ -1736,7 +1748,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail if (!scheme_generate_inlined_test(jitter, branch->test, then_short_ok, &for_this_branch, need_sync)) { CHECK_LIMIT(); - generate_non_tail_with_branch(branch->test, jitter, 0, 1, 0, &for_this_branch); + generate_non_tail_with_branch_and_values(branch->test, jitter, 0, 1, 0, &for_this_branch, NULL); CHECK_LIMIT(); if (for_this_branch.include_slow) { finish_branch(jitter, JIT_R0, &for_this_branch); @@ -1775,7 +1787,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail for_branch->restore_depth++; } g1 = scheme_generate(branch->tbranch, jitter, is_tail, wcm_may_replace, multi_ok, - orig_target, for_branch); + orig_target, for_branch, NULL); if (for_branch) { --for_branch->true_needs_jump; --for_branch->restore_depth; @@ -1845,7 +1857,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail for_branch->restore_depth++; } g2 = scheme_generate(branch->fbranch, jitter, is_tail, wcm_may_replace, multi_ok, - orig_target, for_branch); + orig_target, for_branch, NULL); if (for_branch) { --for_branch->restore_depth; } @@ -1892,7 +1904,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail } int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int wcm_may_replace, int multi_ok, int target, - Branch_Info *for_branch) + Branch_Info *for_branch, Expected_Values_Info *for_values) /* de-sync's; result goes to target */ { Scheme_Type type; @@ -1906,6 +1918,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w mz_jit_state *jitter_copy; Branch_Info *for_branch_copy; Branch_Info_Addr *addrs; + Expected_Values_Info *for_values_copy; int *copy_mappings; copy_mappings = (int *)scheme_malloc_atomic(jitter->mappings_size * sizeof(int)); @@ -1922,6 +1935,11 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w for_branch_copy = NULL; addrs = NULL; } + if (for_values) { + for_values_copy = (Expected_Values_Info *)scheme_malloc_atomic(sizeof(Expected_Values_Info)); + memcpy(for_values_copy, for_values, sizeof(Expected_Values_Info)); + } else + for_values_copy = NULL; p->ku.k.p1 = (void *)obj; p->ku.k.p2 = (void *)jitter_copy; @@ -1931,6 +1949,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w p->ku.k.i3 = target; p->ku.k.p3 = (void *)for_branch_copy; p->ku.k.p4 = (void *)addrs; + p->ku.k.p5 = (void *)for_values_copy; ok = scheme_handle_stack_overflow(generate_k); @@ -1941,6 +1960,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w for_branch->addrs = (Branch_Info_Addr *)SCHEME_CDR(ok); ok = SCHEME_CAR(ok); } + if (for_values) { + memcpy(for_values, for_values_copy, sizeof(Expected_Values_Info)); + } return SCHEME_INT_VAL(ok); } @@ -1951,13 +1973,14 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w if ((target == JIT_R0) && !is_tail && !for_branch + && !for_values && !jitter->unbox && !IS_SKIP_TYPE(SCHEME_TYPE(obj)) && !SAME_TYPE(SCHEME_TYPE(obj), scheme_toplevel_type) && !SAME_TYPE(SCHEME_TYPE(obj), scheme_local_type) && !SAME_TYPE(SCHEME_TYPE(obj), scheme_local_unbox_type) && (SCHEME_TYPE(obj) < _scheme_values_types_)) { - scheme_generate(obj, jitter, is_tail, wcm_may_replace, multi_ok, JIT_R1, for_branch); + scheme_generate(obj, jitter, is_tail, wcm_may_replace, multi_ok, JIT_R1, for_branch, NULL); CHECK_LIMIT(); jit_movr_p(JIT_R0, JIT_R1); return 1; @@ -2471,8 +2494,11 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w LOG_IT(("...in\n")); + if (for_values) + for_values->position++; + return scheme_generate(wcm->body, jitter, is_tail, wcm_may_replace, - multi_ok, orig_target, for_branch); + multi_ok, orig_target, for_branch, for_values); } break; case scheme_boxenv_type: @@ -2509,7 +2535,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_R0); CHECK_LIMIT(); - scheme_generate(p, jitter, is_tail, wcm_may_replace, multi_ok, orig_target, for_branch); + scheme_generate(p, jitter, is_tail, wcm_may_replace, multi_ok, orig_target, for_branch, for_values); END_JIT_DATA(8); @@ -2587,6 +2613,24 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w LOG_IT(("app %d\n", app->num_args)); + if (for_values + && SAME_OBJ(app->args[0], scheme_values_func) + && (app->num_args == for_values->count)) { + int i, pos; + + mz_runstack_skipped(jitter, app->num_args); + + for (i = 0; i < app->num_args; i++) { + scheme_generate_non_tail(app->args[i+1], jitter, 0, 1, 0); + CHECK_LIMIT(); + pos = mz_remap(for_values->position + app->num_args + i); + mz_rs_stxi(pos, JIT_R0); + } + + for_values->delivered = 1; + return 1; + } + r = scheme_generate_inlined_nary(jitter, app, is_tail, multi_ok, NULL, 1, result_ignored, target); CHECK_LIMIT(); if (r) { @@ -2638,6 +2682,28 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w Scheme_Object *args[3]; int r; + if (for_values + && SAME_OBJ(app->rator, scheme_values_func) + && (for_values->count == 2)) { + int pos; + + mz_runstack_skipped(jitter, 2); + + scheme_generate_non_tail(app->rand1, jitter, 0, 1, 0); + CHECK_LIMIT(); + pos = mz_remap(for_values->position + 2); + mz_rs_stxi(pos, JIT_R0); + + scheme_generate_non_tail(app->rand2, jitter, 0, 1, 0); + CHECK_LIMIT(); + pos = mz_remap(for_values->position + 2 + 1); + mz_rs_stxi(pos, JIT_R0); + + for_values->delivered = 1; + + return 1; + } + r = scheme_generate_inlined_binary(jitter, app, is_tail, multi_ok, NULL, 1, 0, result_ignored, target); CHECK_LIMIT(); if (r) { @@ -2682,7 +2748,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w scheme_mz_unbox_restore(jitter, &ubs); return scheme_generate(seq->array[cnt - 1], jitter, is_tail, wcm_may_replace, - multi_ok, orig_target, for_branch); + multi_ok, orig_target, for_branch, for_values); } case scheme_branch_type: { @@ -2745,63 +2811,74 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w } else { /* Expect multiple results: */ GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3; + Expected_Values_Info for_rhs_values; - scheme_generate_non_tail(lv->value, jitter, 1, 1, 0); + for_rhs_values.count = lv->count; + for_rhs_values.position = lv->position; + for_rhs_values.delivered = 0; + + scheme_generate_non_tail_for_values(lv->value, jitter, 1, 1, 0, + ab ? NULL : &for_rhs_values); /* no sync */ CHECK_LIMIT(); - mz_rs_sync(); + if (for_rhs_values.delivered) { + /* Generated code for `lv->value` delivers values to the runstack, + so there's nothing more to do here */ + } else { + mz_rs_sync(); - __START_SHORT_JUMPS__(1); + __START_SHORT_JUMPS__(1); - /* Did we get multiple results? If not, go to error: */ - ref = jit_bnei_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); - /* Load count and result array: */ - mz_tl_ldi_p(JIT_V1, tl_scheme_current_thread); - jit_ldxi_p(JIT_R2, JIT_V1, &((Scheme_Thread *)0x0)->ku.multiple.array); - jit_ldxi_l(JIT_R1, JIT_V1, &((Scheme_Thread *)0x0)->ku.multiple.count); - CHECK_LIMIT(); - /* If we got the expected count, jump to installing values: */ - ref2 = jit_beqi_i(jit_forward(), JIT_R1, lv->count); - /* Otherwise, jump to error: */ - ref3 = jit_jmpi(jit_forward()); - CHECK_LIMIT(); + /* Did we get multiple results? If not, go to error: */ + ref = jit_bnei_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); + /* Load count and result array: */ + mz_tl_ldi_p(JIT_V1, tl_scheme_current_thread); + jit_ldxi_p(JIT_R2, JIT_V1, &((Scheme_Thread *)0x0)->ku.multiple.array); + jit_ldxi_l(JIT_R1, JIT_V1, &((Scheme_Thread *)0x0)->ku.multiple.count); + CHECK_LIMIT(); + /* If we got the expected count, jump to installing values: */ + ref2 = jit_beqi_i(jit_forward(), JIT_R1, lv->count); + /* Otherwise, jump to error: */ + ref3 = jit_jmpi(jit_forward()); + CHECK_LIMIT(); - /* Jump here when we didn't get multiple values. Set count to 1 - and "array" to single value: */ - mz_patch_branch(ref); - jit_movi_i(JIT_R1, 1); - jit_movr_p(JIT_R2, JIT_R0); - CHECK_LIMIT(); + /* Jump here when we didn't get multiple values. Set count to 1 + and "array" to single value: */ + mz_patch_branch(ref); + jit_movi_i(JIT_R1, 1); + jit_movr_p(JIT_R2, JIT_R0); + CHECK_LIMIT(); - /* Error starts here: */ - mz_patch_ucbranch(ref3); - JIT_UPDATE_THREAD_RSPTR_FOR_BRANCH_IF_NEEDED(); - mz_prepare(3); - jit_pusharg_p(JIT_R2); - jit_pusharg_i(JIT_R1); - CHECK_LIMIT(); - jit_movi_i(JIT_V1, lv->count); - jit_pusharg_i(JIT_V1); - (void)mz_finish_lwe(ts_lexical_binding_wrong_return_arity, ref); - CHECK_LIMIT(); + /* Error starts here: */ + mz_patch_ucbranch(ref3); + JIT_UPDATE_THREAD_RSPTR_FOR_BRANCH_IF_NEEDED(); + mz_prepare(3); + jit_pusharg_p(JIT_R2); + jit_pusharg_i(JIT_R1); + CHECK_LIMIT(); + jit_movi_i(JIT_V1, lv->count); + jit_pusharg_i(JIT_V1); + (void)mz_finish_lwe(ts_lexical_binding_wrong_return_arity, ref); + CHECK_LIMIT(); - /* Continue with expected values; R2 has values and V1 has thread pointer: */ - mz_patch_branch(ref2); - __END_SHORT_JUMPS__(1); - (void)jit_movi_p(JIT_R0, NULL); - jit_stxi_p(&((Scheme_Thread *)0x0)->ku.multiple.array, JIT_V1, JIT_R0); - for (i = 0; i < lv->count; i++) { - jit_ldxi_p(JIT_R1, JIT_R2, WORDS_TO_BYTES(i)); - if (ab) { - pos = mz_remap(lv->position + i); - jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); - jit_str_p(JIT_R0, JIT_R1); - } else { - pos = mz_remap(lv->position + i); - jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_R1); - } - CHECK_LIMIT(); - } + /* Continue with expected values; R2 has values and V1 has thread pointer: */ + mz_patch_branch(ref2); + __END_SHORT_JUMPS__(1); + (void)jit_movi_p(JIT_R0, NULL); + jit_stxi_p(&((Scheme_Thread *)0x0)->ku.multiple.array, JIT_V1, JIT_R0); + for (i = 0; i < lv->count; i++) { + jit_ldxi_p(JIT_R1, JIT_R2, WORDS_TO_BYTES(i)); + if (ab) { + pos = mz_remap(lv->position + i); + jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + jit_str_p(JIT_R0, JIT_R1); + } else { + pos = mz_remap(lv->position + i); + jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_R1); + } + CHECK_LIMIT(); + } + } } END_JIT_DATA(14); @@ -2811,7 +2888,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w scheme_mz_unbox_restore(jitter, &ubs); return scheme_generate(lv->body, jitter, is_tail, wcm_may_replace, - multi_ok, orig_target, for_branch); + multi_ok, orig_target, for_branch, for_values); } case scheme_let_void_type: { @@ -2862,8 +2939,11 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w scheme_mz_unbox_restore(jitter, &ubs); + if (for_values) + for_values->position += c; + return scheme_generate(lv->body, jitter, is_tail, wcm_may_replace, - multi_ok, orig_target, for_branch); + multi_ok, orig_target, for_branch, for_values); } case scheme_letrec_type: { @@ -2934,7 +3014,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w scheme_mz_unbox_restore(jitter, &ubs); return scheme_generate(l->body, jitter, is_tail, wcm_may_replace, - multi_ok, orig_target, for_branch); + multi_ok, orig_target, for_branch, for_values); } case scheme_let_one_type: { @@ -3022,8 +3102,11 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w scheme_mz_unbox_restore(jitter, &ubs); + if (for_values) + for_values->position++; + return scheme_generate(lv->body, jitter, is_tail, wcm_may_replace, - multi_ok, orig_target, for_branch); + multi_ok, orig_target, for_branch, for_values); } case scheme_with_cont_mark_type: { @@ -3078,7 +3161,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w jitter->pushed_marks++; return scheme_generate(wcm->body, jitter, is_tail, wcm_may_replace, - multi_ok, orig_target, for_branch); + multi_ok, orig_target, for_branch, for_values); } case scheme_quote_syntax_type: { @@ -3656,7 +3739,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) /* Generate code for the body: */ jitter->need_set_rs = 1; - r = scheme_generate(data->code, jitter, 1, 1, 1, JIT_R0, NULL); /* no need for sync */ + r = scheme_generate(data->code, jitter, 1, 1, 1, JIT_R0, NULL, NULL); /* no need for sync */ /* Result is in JIT_R0 */ CHECK_LIMIT(); diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 86db646ac1..9f6746d79e 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -462,6 +462,12 @@ typedef struct { Branch_Info_Addr *addrs; } Branch_Info; +typedef struct { + int position; + int count; + char delivered; +} Expected_Values_Info; + #define mz_CURRENT_REG_STATUS_VALID() (jitter->status_at_ptr == _jit.x.pc) #define mz_SET_REG_STATUS_VALID(v) (jitter->status_at_ptr = (v ? _jit.x.pc : 0)) @@ -1528,8 +1534,10 @@ int scheme_generate_struct_op(mz_jit_state *jitter, int kind, int for_branch, int scheme_generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends, int ignored); int scheme_generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends, int ignored, Branch_Info *for_branch); +int scheme_generate_non_tail_for_values(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends, int ignored, + Expected_Values_Info *for_values); int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int tail_ok, int wcm_may_replace, int multi_ok, int target, - Branch_Info *for_branch); + Branch_Info *for_branch, Expected_Values_Info *for_values); int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway); void scheme_generate_function_prolog(mz_jit_state *jitter); diff --git a/racket/src/racket/src/jitarith.c b/racket/src/racket/src/jitarith.c index 6df1809f91..dac72dfc3a 100644 --- a/racket/src/racket/src/jitarith.c +++ b/racket/src/racket/src/jitarith.c @@ -2138,7 +2138,7 @@ static int extract_nary_arg(int reg, int n, mz_jit_state *jitter, Scheme_App_Rec scheme_generate_unboxing(jitter, JIT_R0); } else if (scheme_is_constant_and_avoids_r1(app->args[n+1])) { __END_SHORT_JUMPS__(old_short_jumps); - scheme_generate(app->args[n+1], jitter, 0, 0, 0, reg, NULL); + scheme_generate(app->args[n+1], jitter, 0, 0, 0, reg, NULL, NULL); CHECK_LIMIT(); __START_SHORT_JUMPS__(old_short_jumps); } else { diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index 4d472dfa5f..e567bfead0 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -1375,7 +1375,7 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i mz_rs_stxi(num_rands - 1, JIT_R0); } - scheme_generate(rator, jitter, 0, 0, 0, JIT_V1, NULL); + scheme_generate(rator, jitter, 0, 0, 0, JIT_V1, NULL, NULL); CHECK_LIMIT(); mz_rs_sync(); @@ -1708,7 +1708,7 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos } /* Reset V1 to rator for slow path: */ - scheme_generate(rator, jitter, 0, 0, 0, JIT_V1, NULL); + scheme_generate(rator, jitter, 0, 0, 0, JIT_V1, NULL, NULL); mz_rs_sync(); return 1; @@ -2073,7 +2073,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ #endif if (inline_direct_args) { if (inline_direct_args[i].gen) - scheme_generate(arg, jitter, 0, 0, 0, inline_direct_args[i].reg, NULL); + scheme_generate(arg, jitter, 0, 0, 0, inline_direct_args[i].reg, NULL, NULL); } else scheme_generate_non_tail(arg, jitter, 0, !need_non_tail, 0); /* sync'd below */ RESUME_JIT_DATA(); @@ -2114,7 +2114,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (reorder_ok && !inline_direct_native) { if ((no_call < 2) && !apply_to_list) { - scheme_generate(rator, jitter, 0, 0, 0, JIT_V1, NULL); /* sync'd below, or not */ + scheme_generate(rator, jitter, 0, 0, 0, JIT_V1, NULL, NULL); /* sync'd below, or not */ } CHECK_LIMIT(); } diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index a43e1cb664..ff47e3da65 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -2101,7 +2101,7 @@ int scheme_generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ jit_movr_p(JIT_R1, JIT_R0); - scheme_generate(rand2, jitter, 0, 0, 0, JIT_R0, NULL); /* no sync... */ + scheme_generate(rand2, jitter, 0, 0, 0, JIT_R0, NULL, NULL); /* no sync... */ CHECK_LIMIT(); if (order_matters) { @@ -2165,12 +2165,12 @@ int scheme_generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ mz_runstack_skipped(jitter, skipped); if (simple2 && !order_matters && already_in_register(rand1, jitter)) { - scheme_generate(rand1, jitter, 0, 0, 0, JIT_R1, NULL); /* no sync... */ - scheme_generate(rand2, jitter, 0, 0, 0, JIT_R0, NULL); /* no sync... */ + scheme_generate(rand1, jitter, 0, 0, 0, JIT_R1, NULL, NULL); /* no sync... */ + scheme_generate(rand2, jitter, 0, 0, 0, JIT_R0, NULL, NULL); /* no sync... */ direction = -1; } else { if (simple2) { - scheme_generate(rand2, jitter, 0, 0, 0, JIT_R1, NULL); /* no sync... */ + scheme_generate(rand2, jitter, 0, 0, 0, JIT_R1, NULL, NULL); /* no sync... */ CHECK_LIMIT(); } else { scheme_generate_non_tail(rand2, jitter, 0, 1, 0); /* no sync... */ @@ -2178,7 +2178,7 @@ int scheme_generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ jit_movr_p(JIT_R1, JIT_R0); } - scheme_generate(rand1, jitter, 0, 0, 0, JIT_R0, NULL); /* no sync... */ + scheme_generate(rand1, jitter, 0, 0, 0, JIT_R0, NULL, NULL); /* no sync... */ } CHECK_LIMIT(); @@ -4065,7 +4065,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int MZ_FPUSEL_STMT_ONLY(extfl, --jitter->unbox_extflonum); } else { if (constval) - scheme_generate(app->args[3], jitter, 0, 0, 0, JIT_R2, NULL); /* sync'd below */ + scheme_generate(app->args[3], jitter, 0, 0, 0, JIT_R2, NULL, NULL); /* sync'd below */ else { scheme_generate_non_tail(app->args[3], jitter, 0, 1, 0); /* sync'd below */ jit_movr_p(JIT_R2, JIT_R0); @@ -4078,7 +4078,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int Need to get vec into R0, non-simple index into R1, value into R2. */ if (can_delay_vec) { - scheme_generate(app->args[1], jitter, 0, 0, 0, JIT_R0, NULL); /* sync'd below */ + scheme_generate(app->args[1], jitter, 0, 0, 0, JIT_R0, NULL, NULL); /* sync'd below */ CHECK_LIMIT(); } else if (can_delay_index && constval) { jit_movr_p(JIT_R0, JIT_V1); @@ -4088,7 +4088,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int if (!simple) { if (can_delay_index) { - scheme_generate(app->args[2], jitter, 0, 0, 0, JIT_R1, NULL); /* sync'd below */ + scheme_generate(app->args[2], jitter, 0, 0, 0, JIT_R1, NULL, NULL); /* sync'd below */ CHECK_LIMIT(); } else if (!constval) { if (can_delay_vec) @@ -4282,9 +4282,9 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int CHECK_LIMIT(); if (!got_two) { - scheme_generate(app->args[2], jitter, 0, 0, 0, JIT_R1, NULL); + scheme_generate(app->args[2], jitter, 0, 0, 0, JIT_R1, NULL, NULL); CHECK_LIMIT(); - scheme_generate(app->args[1], jitter, 0, 0, 0, JIT_R0, NULL); + scheme_generate(app->args[1], jitter, 0, 0, 0, JIT_R0, NULL, NULL); mz_runstack_unskipped(jitter, 3); } else { mz_rs_ldr(JIT_R0); From cbb4ffee4d7995b1f441fd06c20113f241789302 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 23 Aug 2015 18:37:45 -0600 Subject: [PATCH 095/381] JIT: replace a multiplcation with a shift In the implementation of `with-continuation-mark`. --- racket/src/racket/src/jitcommon.c | 6 ++---- racket/src/racket/src/schpriv.h | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 665ff8b904..cfc53e8473 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -2591,8 +2591,7 @@ static int common6(mz_jit_state *jitter, void *_data) CHECK_LIMIT(); jit_andi_l(JIT_V1, JIT_R2, SCHEME_MARK_SEGMENT_MASK); - jit_movi_l(JIT_R1, sizeof(Scheme_Cont_Mark)); - jit_mulr_l(JIT_V1, JIT_V1, JIT_R1); + jit_lshi_l(JIT_V1, JIT_V1, LOG_CONT_MARK_WORD_COUNT+JIT_LOG_WORD_SIZE); jit_addr_l(JIT_R0, JIT_R0, JIT_V1); CHECK_LIMIT(); /* R0 now points to the right record */ @@ -2649,8 +2648,7 @@ static int common6(mz_jit_state *jitter, void *_data) /* R0 now points to the right array */ jit_andi_l(JIT_V1, JIT_R2, SCHEME_MARK_SEGMENT_MASK); - jit_movi_l(JIT_R1, sizeof(Scheme_Cont_Mark)); - jit_mulr_l(JIT_V1, JIT_V1, JIT_R1); + jit_lshi_l(JIT_V1, JIT_V1, LOG_CONT_MARK_WORD_COUNT+JIT_LOG_WORD_SIZE); jit_addr_l(JIT_R0, JIT_R0, JIT_V1); CHECK_LIMIT(); /* R0 now points to the right record */ diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index d477767b74..8f5e2c62fb 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1687,6 +1687,7 @@ typedef struct Scheme_Cont_Mark { Scheme_Object *cache; /* chain and/or shortcut */ MZ_MARK_POS_TYPE pos; /* Odd numbers - so they look like non-pointers */ } Scheme_Cont_Mark; +#define LOG_CONT_MARK_WORD_COUNT 2 void scheme_new_mark_segment(Scheme_Thread *p); From b9a5e92c37011fb130eba105bcad82d86fab17ce Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 24 Aug 2015 15:06:34 -0600 Subject: [PATCH 096/381] file-truncate: flush on Windows before truncating Otherwise, writes to the output port can get lost. --- racket/src/racket/src/port.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 4ee437fefc..de69a09505 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -5593,6 +5593,7 @@ Scheme_Object *scheme_file_truncate(int argc, Scheme_Object *argv[]) errid = -1; #ifdef WINDOWS_FILE_HANDLES + flush_fd(scheme_output_port_record(argv[0]), NULL, 0, 0, 0, 0); if (win_seekable(fd)) { DWORD r; LONG lo_w, hi_w, old_lo_w, old_hi_w; From e2b27be099e24669b96dee9ffc8f19524f64ff51 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 24 Aug 2015 09:47:20 -0600 Subject: [PATCH 097/381] file/ico: support PNG icons and arbitrary icon-set replacement Support PNG-encoded icons in ".ico" files and executables. For executables, instead of supporting only new icons that match the sizes and encodings of existing icons in an executable, support arbitrary replacement icons in an executable. The improved funcitonality relies on a new library (currently private) for general updates to a Windows executable's resources. --- pkgs/racket-doc/file/scribblings/ico.scrbl | 69 ++- racket/collects/compiler/private/pe-rsrc.rkt | 606 +++++++++++++++++++ racket/collects/file/ico.rkt | 269 ++++---- 3 files changed, 812 insertions(+), 132 deletions(-) create mode 100644 racket/collects/compiler/private/pe-rsrc.rkt diff --git a/pkgs/racket-doc/file/scribblings/ico.scrbl b/pkgs/racket-doc/file/scribblings/ico.scrbl index 3753e84b8a..f69335df06 100644 --- a/pkgs/racket-doc/file/scribblings/ico.scrbl +++ b/pkgs/racket-doc/file/scribblings/ico.scrbl @@ -10,7 +10,8 @@ and writing @filepath{.ico} files, which contain one or more icons. Each icon is up to 256 by 256 pixels, has a particular depth (i.e., bits per pixel used to represent a color), and mask (i.e., whether a pixel is shown, except that the mask may be ignored for 32-bit icons -that have an alpha value per pixel). +that have an alpha value per pixel). The library also provides support +for reading and writing icons in Windows executables. @defproc[(ico? [v any/c]) boolean?]{ @@ -18,25 +19,40 @@ Returns @racket[#t] if @racket[v] represents an icon, @racket[#f] otherwise.} @deftogether[( -@defproc[(ico-width [ico ico?]) (integer-in 1 256)] -@defproc[(ico-height [ico ico?]) (integer-in 1 256)] +@defproc[(ico-width [ico ico?]) exact-positive-integer?] +@defproc[(ico-height [ico ico?]) exact-positive-integer?] @defproc[(ico-depth [ico ico?]) (one-of/c 1 2 4 8 16 24 32)] )]{ Returns the width or height of an icon in pixels, or the depth in bits per -pixel.} +pixel. + +@history[#:changed "6.2.900.10" @elem{A PNG-format icon can have a + width or height greater than 256.}]} + + +@deftogether[( +@defproc[(ico-format [ico ico?]) (or/c 'bmp 'png)] +)]{ + +Reports the format of the icon. + +@history[#:added "6.2.900.10"]} + @defproc[(read-icos [src (or/c path-string? input-port?)]) (listof ico?)]{ Parses @racket[src] as an @filepath{.ico} to extract a list of icons.} + @defproc[(read-icos-from-exe [src (or/c path-string? input-port?)]) (listof ico?)]{ Parses @racket[src] as an @filepath{.exe} to extract the list of icons that represent the Windows executable.} + @defproc[(write-icos [icos (listof ico?)] [dest (or/c path-string? output-port?)] [#:exists exists (or/c 'error 'append 'update 'can-update @@ -50,22 +66,46 @@ Writes each icon in @racket[icos] to @racket[dest] as an @racket[exists] is passed on to @racket[open-output-file] to open @racket[dest] for writing.} + @defproc[(replace-icos [icos (listof ico?)] - [dest (or/c path-string? output-port?)]) + [dest path-string?]) void?]{ Writes icons in @racket[icos] to replace icons in @racket[dest] as an Windows executable. Only existing icon sizes and depths in the -executable are replaced, and best matches for the existing sizes and -depth are drawn from @racket[icos] (adjusting the scale and depth f a -best match as necessary).} +executable are replaced, and only when the encoding sizes match. +Best matches for the existing sizes and +depth are drawn from @racket[icos] (adjusting the scale and depth of a +best match as necessary). + +Use @racket[replace-all-icos], instead, to replace a set of icons +wholesale, especially when the set include PNG-format icons.} + + +@defproc[(replace-all-icos [icos (listof ico?)] + [dest (or/c path-string? output-port?)]) + void?]{ + +Replaces the icon set in the executable @racket[dest] with the given +set of icons.} + @defproc[(ico->argb [ico ico?]) bytes?]{ -Converts an icon to an ARGB byte string, which has the icon's pixels +Converts an icon in BMP format (see @racket[ico-format]) +to an ARGB byte string, which has the icon's pixels in left-to-right, top-to-bottom order, with four bytes (alpha, red, green, and blue channels) for each pixel.} + +@defproc[(ico->png-bytes [ico ico?]) bytes?]{ + +Returns the bytes of a PNG encoding for an icon in PNG format (see +@racket[ico-format]). + +@history[#:added "6.2.900.10"]} + + @defproc[(argb->ico [width (integer-in 1 256)] [height (integer-in 1 256)] [bstr bytes?] @@ -73,7 +113,16 @@ green, and blue channels) for each pixel.} ico?]{ Converts an ARGB byte string (in the same format as from -@racket[ico->argb]) to an icon of the given width, height, and depth. +@racket[ico->argb]) to an icon of the given width, height, and depth +in BMP format. The @racket[bstr] argument must have a length @racket[(* 4 width height)], and @racket[(* width depth)] must be a multiple of 8.} + + +@defproc[(png-bytes->ico [bstr bytes?]) + ico?]{ + +Wraps the given PNG encoding as a PNG-encoded icon. + +@history[#:added "6.2.900.10"]} diff --git a/racket/collects/compiler/private/pe-rsrc.rkt b/racket/collects/compiler/private/pe-rsrc.rkt new file mode 100644 index 0000000000..be11e2e7ad --- /dev/null +++ b/racket/collects/compiler/private/pe-rsrc.rkt @@ -0,0 +1,606 @@ +#lang racket/base +(require racket/contract + racket/pretty) + +(provide read-pe+resources + update-resources + + resource-ref + resource-ref/path + resource-set + resource-remove) + +(define (byte->integer p) + (read-byte p)) +(define (word->integer p) + (integer-bytes->integer (read-bytes 2 p) #f #f)) +(define (dword->integer p) + (integer-bytes->integer (read-bytes 4 p) #f #f)) +(define (xword->integer p) + (integer-bytes->integer (read-bytes 8 p) #f #f)) + +(define (integer->word i p) + (display (integer->integer-bytes i 2 #f #f) p)) +(define (integer->dword i p) + (display (integer->integer-bytes i 4 #f #f) p)) +(define (integer->3/2word i p) + (display (subbytes (integer->integer-bytes i 4 #f #f) 0 3) p)) + +(define (flag v) + (positive? (bitwise-and #x80000000 v))) +(define (value v) + (bitwise-and #x7FFFFFFF v)) +(define (add-flag v) + (bitwise-ior #x80000000 v)) + +(define-logger pe-rsrc) + +(define (skip-to-image-headers-after-signature p) + ;; p is expected to be a file port + (define dos-sig (word->integer p)) + (unless (= #x5A4D dos-sig) + (error 'pe-rsrc "bad DOS signature ~x" dos-sig)) + (file-position p 60) + (let ([pos (dword->integer p)]) + ;; pos points to IMAGE_NT_HEADERS + ;; (log-error "at ~s" pos) + (file-position p pos) + (define sig (dword->integer p)) + (unless (= #x4550 sig) ; = #"PE\0\0" + (error 'pe-rsrc "bad PE signature ~x" sig)) + pos)) + +(struct pe (sections section-alignment file-alignment + image-size-pos section-start-pos rsrc-offset rsrc-virtual-addr rsrc-size)) +(struct section (name virtual-size virtual-addr + file-length file-position + characteristics) + #:prefab) + +(define (read-pe p) + (let ([pos (skip-to-image-headers-after-signature p)]) + (word->integer p) ; skip machine + (let ([num-sections (word->integer p)] + [_ (begin (dword->integer p) ; date time stamp + (dword->integer p) ; symbol table - 0 for modern exes + (dword->integer p))] ; symbol count - 0 for modern exes + [size (word->integer p)]) ; size of optional headers + (file-position p (+ pos 4 20)) + (define image-type + (case (word->integer p) + [(#x10B) 'pe32] + [(#x20B) 'pe32+] + [else (error "unrecognized image type")])) + (file-position p (+ pos 4 20 32)) + (define section-alignment (dword->integer p)) + (define file-alignment (dword->integer p)) + (log-pe-rsrc-debug "alignment ~x ~x" section-alignment file-alignment) + (define image-size-pos (+ pos 4 20 56)) + (file-position p image-size-pos) + (log-pe-rsrc-debug "image size ~x" (dword->integer p)) + ;;(file-position p (+ pos 4 20 64)) + ;;(log-error "checksum ~x at ~a" (dword->integer p) (+ pos 4 20 64)) + ;;(file-position p (+ pos 4 20 (if (eq? image-type 'pe32) 92 108))) + ;;(log-error "extra entries ~a in ~a" (dword->integer p) size) + (define rsrc-offset (+ pos 4 20 (if (eq? image-type 'pe32) 112 128))) + (file-position p rsrc-offset) + (define rsrc-virtual-addr (dword->integer p)) + (define rsrc-size (dword->integer p)) + (define section-start-pos (+ pos + 4 ; Signature : DWORD + 20 ; FileHeader: IMAGE_FILE_HEADER + size)) ; "optional" header + (define (z v) (unless (zero? v) (error "expected zero"))) + (pe (let sloop ([i 0] [section-pos section-start-pos]) + (if (= i num-sections) + null + (begin + (file-position p section-pos) + ;; p points to an IMAGE_SECTION_HEADER + (cons (section (read-bytes 8 p) ; name + (dword->integer p) ; virtual size + (dword->integer p) ; virtual address + (dword->integer p) ; length + (dword->integer p) ; file pos + (begin + (z (dword->integer p)) ; relocations (zero) + (z (dword->integer p)) ; line numbers (zero) + (z (word->integer p)) ; num relocations (zero) + (z (word->integer p)) ; num line numbers (zero) + (dword->integer p))) ; characteristics + (sloop (add1 i) (+ section-pos 40)))))) + section-alignment + file-alignment + image-size-pos + section-start-pos + rsrc-offset + rsrc-virtual-addr + rsrc-size)))) + +(define (show-sections sections) + (for/fold ([prev-end 0] [prev-full-end 0]) ([s (in-list sections)]) + (log-pe-rsrc-debug "~s ~x [+~x/+~x] @ ~x ~x [-> ~x] $~x" + (section-name s) + (section-virtual-addr s) + (- (section-virtual-addr s) prev-end) + (- (section-virtual-addr s) prev-full-end) + (section-file-position s) + (section-file-length s) + (section-virtual-size s) + (section-characteristics s)) + (values (+ (section-virtual-addr s) + (section-virtual-size s)) + (+ (section-virtual-addr s) + (section-file-length s)))) + (void)) + +(define (show-resources rsrcs [indent ""]) + (cond + [(directory? rsrcs) + (log-pe-rsrc-debug "~a~s" indent (entry-name rsrcs)) + (for ([e (in-list (directory-content rsrcs))]) + (show-resources e (string-append indent " ")))] + [else + (log-pe-rsrc-debug "~a~s ~x ~s at ~x" indent (entry-name rsrcs) + (bytes-length (resource-content rsrcs)) + (resource-codepage rsrcs) + (resource-file-pos rsrcs))])) + +(struct entry (name) #:prefab) +(struct directory entry (timestamp major-version minor-version content) #:prefab) +(struct resource entry (content codepage file-pos) #:prefab) + +(define (read-rsrcs p rsrc-pos rsrc-virtual-addr) + (let loop ([dir-name #f] [dir-pos 0] [depth 0]) + (file-position p (+ rsrc-pos dir-pos 4)) + (let ([timestamp (dword->integer p)] + [major-version (word->integer p)] + [minor-version (word->integer p)] + [num-named (word->integer p)] + [num-ided (word->integer p)]) + ;;(log-error "dir at ~x[~a]: ~a+~a" dir-pos depth num-named num-ided) + (directory + dir-name + timestamp + major-version + minor-version + (let iloop ([i 0]) + (if (= i (+ num-ided num-named)) + null + (let ([name-delta (dword->integer p)] + [data-delta (dword->integer p)] + [next (file-position p)]) + (cons + (let ([name (if (i . < . num-named) + (begin + ;;(log-error "name at ~x = ~x" (value name-delta) (+ rsrc-pos (value name-delta))) + (file-position p (+ rsrc-pos (value name-delta))) + (let* ([len (word->integer p)]) + ;; len is in unicode chars... + (let ([unistr (read-bytes (* 2 len) p)]) + ;; Assume it fits into ASCII... + (regexp-replace* "\0" + (bytes->string/latin-1 unistr) + "")))) + name-delta)]) + (if (flag data-delta) + ;; Directory: + (loop name (value data-delta) (add1 depth)) + ;; Entry: + (begin + (file-position p (+ rsrc-pos (value data-delta))) + (let ([rva (dword->integer p)] + [size (dword->integer p)] + [codepage (dword->integer p)]) + ;;(log-error "resource at ~x ~x" (value data-delta) size) + (define file-pos (+ rva + (- rsrc-pos + rsrc-virtual-addr))) + (file-position p file-pos) + (resource name + (read-bytes size p) + codepage + file-pos))))) + (begin + (file-position p next) + (iloop (add1 i))))))))))) + +(define (write-rsrcs rsrcs p virtual-addr) + (define (sorted-directory-content e) + (sort (directory-content e) + #:key entry-name + (lambda (a b) + (cond + [(string? a) + (if (string? a) + (stringdword 0 p) + (integer->dword (directory-timestamp e) p) + (integer->word (directory-major-version e) p) + (integer->word (directory-minor-version e) p) + (define num-strs (let loop ([cs content]) + (cond + [(null? cs) 0] + [(number? (entry-name (car cs))) 0] + [else (+ 1 (loop (cdr cs)))]))) + (integer->word num-strs p) + (integer->word (- (length content) num-strs) p) + (for/fold ([str-pos str-pos] [res-pos res-pos]) ([e (in-list content)]) + (values (cond + [(string? (entry-name e)) + (integer->dword (add-flag str-pos) p) + (+ str-pos (str-size (entry-name e)))] + [else + (integer->dword (entry-name e) p) + str-pos]) + (cond + [(resource? e) + (integer->dword res-pos p) + (+ res-pos 16)] + [else + (integer->dword (add-flag (hash-ref dir-pos-ht e)) p) + res-pos])))])) + + ;; Write out resource data entries + (for/fold ([data-pos data-start]) ([e (in-list entries)]) + (cond + [(resource? e) + (define len (align-data-size (bytes-length (resource-content e)))) + (integer->dword (+ data-pos virtual-addr) p) + (integer->dword len p) + (integer->dword (resource-codepage e) p) + (integer->dword 0 p) + (+ data-pos len)] + [else + data-pos])) + + ;; Write out strings + (for ([e (in-list entries)]) + (define n (entry-name e)) + (when (string? n) + (integer->word (string-length n) p) + (for ([c (in-string n)]) + (integer->word (char->integer c) p)) + (when align-strings? + (when (even? (string-length n)) + (integer->word 0 p))))) + (write-bytes (make-bytes (- aligned-str-length str-length)) p) + + ;; Write out resource content + (for ([e (in-list entries)]) + (when (resource? e) + (define bstr (resource-content e)) + (write-bytes bstr p) + (define aligned-size (align-data-size (bytes-length bstr))) + (write-bytes (make-bytes (- aligned-size (bytes-length bstr))) p))) + + (void)) + + +(define (find-section sections find-name) + (let loop ([sections sections]) + (cond + [(null? sections) + (error 'find-section "can't find section: ~e" find-name)] + [else + (define s (car sections)) + (if (bytes=? find-name (section-name s)) + s + (loop (cdr sections)))]))) + +(define rsrc-section-name #".rsrc\0\0\0") + +(define (read-pe+resources i) + (define pe (read-pe i)) + (define s (find-section (pe-sections pe) rsrc-section-name)) + + (log-pe-rsrc-debug "sections at ~x" (pe-section-start-pos pe)) + (show-sections (pe-sections pe)) + (log-pe-rsrc-debug "rsrc at ~x ~x" (pe-rsrc-virtual-addr pe) (pe-rsrc-size pe)) + + (unless (and (= (section-virtual-addr s) (pe-rsrc-virtual-addr pe)) + (>= (section-virtual-size s) (pe-rsrc-size pe))) + (error 'pe-rsrc + "sections and resource information do not line up in the typical way")) + + (define rsrcs (read-rsrcs i (section-file-position s) (section-virtual-addr s))) + + (show-resources rsrcs) + + (values pe rsrcs)) + +(define (same-alignment orig new) + (cond + [(bitwise-bit-set? orig 1) + new] + [(bitwise-bit-set? new 1) + (same-alignment orig (add1 new))] + [else + (arithmetic-shift (same-alignment + (arithmetic-shift orig -1) + (arithmetic-shift new -1)) + 1)])) + +(define (update-sections pe new-sections o) + (file-position o (pe-section-start-pos pe)) + (for ([s (in-list new-sections)]) + (write-bytes (section-name s) o) + (integer->dword (section-virtual-size s) o) + (integer->dword (section-virtual-addr s) o) + (integer->dword (section-file-length s) o) + (integer->dword (section-file-position s) o) + (integer->dword 0 o) + (integer->dword 0 o) + (integer->word 0 o) + (integer->word 0 o) + (integer->dword (section-characteristics s) o))) + +(define (update-resources src pe rsrcs) + (define o (open-output-bytes)) + (write-rsrcs rsrcs o (pe-rsrc-virtual-addr pe)) + (define bstr (get-output-bytes o)) + (define len (bytes-length bstr)) + + (define s (find-section (pe-sections pe) rsrc-section-name)) + (cond + [(len . <= . (section-file-length s)) + (log-pe-rsrc-debug "new content fits in place of old content") + (call-with-output-file + src + #:exists 'update + (lambda (o) + (file-position o (section-file-position s)) + (write-bytes bstr o) + (write-bytes (make-bytes (- (section-file-length s) len)) o) + + (file-position o (pe-rsrc-offset pe)) + (integer->dword (pe-rsrc-virtual-addr pe) o) + (integer->dword len o)))] + [else + (log-pe-rsrc-debug "moving resources to end") + (define new-virtual-addr + (same-alignment + (section-virtual-addr s) + (for/fold ([pos 0]) ([s2 (in-list (pe-sections pe))] + #:unless (eq? s s2)) + (max pos + (+ (section-virtual-addr s2) + (section-virtual-size s2)))))) + + (define o (open-output-bytes)) + (write-rsrcs rsrcs o new-virtual-addr) + (define bstr (get-output-bytes o)) + (define len (bytes-length bstr)) + + (define new-virtual-size len) + (define new-file-size (same-alignment (pe-section-alignment pe) len)) + (define new-position + (let ([fs (file-size src)]) + (cond + [(= fs (+ (section-file-position s) + (section-file-length s))) + ;; Section was already at end, so overwrite is ok + (section-file-position s)] + [else + (same-alignment (pe-file-alignment pe) fs)]))) + (log-pe-rsrc-debug "moving to ~x ~x at ~x" + new-virtual-addr + new-virtual-size + new-position) + + (define new-sections + (sort (for/list ([s2 (in-list (pe-sections pe))]) + (if (eq? s s2) + (section (section-name s) + new-virtual-size new-virtual-addr + new-file-size new-position + (section-characteristics s)) + s2)) + < + #:key section-virtual-addr)) + + (call-with-output-file + src + #:exists 'update + (lambda (o) + (define exe-size (+ new-position new-file-size)) + + (update-sections pe new-sections o) + + (file-position o new-position) + (write-bytes bstr o) + (write-bytes (make-bytes (- new-file-size len)) o) + + (file-position o (pe-rsrc-offset pe)) + (integer->dword new-virtual-addr o) + (integer->dword new-virtual-size o) + + (file-position o (pe-image-size-pos pe)) + (integer->dword (+ new-virtual-addr new-file-size) o) + + (file-truncate o exe-size)))])) + +;; ---------------------------------------- + +(define (get-match dir n) + (and dir + (for/or ([e (in-list (directory-content dir))]) + (and (or (not n) + (equal? n (entry-name e))) + e)))) + +(define (set-match dir v + #:name [name (entry-name v)] + #:can-remove? [can-remove? #f]) + (define new-content + (let loop ([c (directory-content dir)]) + (cond + [(null? c) (if v + (list v) + null)] + [(or (not name) + (equal? (entry-name (car c)) name)) + (if v + (cons v (cdr c)) + (cdr c))] + [else (cons (car c) (loop (cdr c)))]))) + (if (and can-remove? (null? new-content)) + #f + (struct-copy directory dir + [content new-content]))) + +(define (resource-ref/path rsrcs type name language) + (define t (get-match rsrcs type)) + (define n (get-match t name)) + (define r (get-match n language)) + (values (and t (entry-name t)) + (and n (entry-name n)) + (and r (entry-name r)) + (and r (resource-content r)) + (and r (resource-file-pos r)))) + +(define (resource-ref rsrcs type name language) + (define-values (t n l v p) (resource-ref/path rsrcs type name language)) + v) + +(define (resource-set rsrcs type name language v) + (define (mk name what) + (directory (or name + (error 'resource-set + "cannot infer ~a" + what)) + 0 ; timestamp + 0 ; major-version + 0 ; minor-version + null)) + (define t (or (get-match rsrcs type) (mk type 'type))) + (define n (or (get-match t name) (mk name 'name))) + (define l (get-match n language)) + (set-match rsrcs #:name type + (set-match t + #:name name + (set-match n + #:name language + (resource (or language + (and l (entry-name l)) + (error 'resource-set + "cannot infer language")) + v + 1252 + 0))))) + +(define (resource-remove rsrcs type name language) + (define t (get-match rsrcs type)) + (define n (get-match t name)) + (if (get-match n language) + (set-match rsrcs #:name type + (set-match t + #:name name + #:can-remove? #t + (set-match n + #:name language + #:can-remove? #t + #f))) + rsrcs)) + +#; +(module+ test + (define-syntax-rule (check a b ...) + (let ([got (call-with-values (lambda () a) list)] + [expect (list b ...)]) + (unless (equal? got expect) + (error 'test "failed: ~.s\n got: ~e" 'a got)))) + (define (d name l) + (directory name 0 0 0 l)) + (check (resource-ref (d #f null) #f #f #f) + #f) + (define hi-d (d #f (list (d 1 (list (d "hi" (list (resource 1033 #"ok" 1252 0)))))))) + (define hi2-d (d #f (list (d 1 (list (d "hi" (list (resource 1033 #"yep" 1252 0)))))))) + (check (resource-set (d #f null) 1 "hi" 1033 #"ok") + hi-d) + (check (resource-remove hi-d #f "no-hi" #f) + hi-d) + (check (resource-remove hi-d #f "hi" #f) + (d #f null)) + (check (resource-set hi-d #f "hi" #f #"yep") + hi2-d) + (define bye-d (d #f (list (d 1 (list (d "hi" (list (resource 1033 #"ok" 1252 0))) + (d "bye" (list (resource 1033 #"ok" 1252 0)))))))) + (check (resource-set hi-d 1 "bye" 1033 #"ok") + bye-d) + (check (resource-remove bye-d 1 "bye" #f) + hi-d)) + diff --git a/racket/collects/file/ico.rkt b/racket/collects/file/ico.rkt index cb7658ccb8..9bc7662227 100644 --- a/racket/collects/file/ico.rkt +++ b/racket/collects/file/ico.rkt @@ -1,11 +1,13 @@ #lang racket/base -(require racket/contract) +(require racket/contract + compiler/private/pe-rsrc) (provide ico? (contract-out - [ico-width (ico? . -> . (integer-in 1 256))] - [ico-height (ico? . -> . (integer-in 1 256))] - [ico-depth (ico? . -> . (one-of/c 1 2 4 8 16 24 32))] + [ico-width (ico? . -> . exact-positive-integer?)] + [ico-height (ico? . -> . exact-positive-integer?)] + [ico-depth (ico? . -> . (or/c 1 2 4 8 16 24 32))] + [ico-format (ico? . -> . (or/c 'bmp 'png))] [read-icos ((or/c path-string? input-port?) . -> . (listof ico?))] [read-icos-from-exe ((or/c path-string? input-port?) . -> . (listof ico?))] @@ -16,14 +18,19 @@ 'must-truncate 'truncate/replace)] . ->* . void?)] - [replace-icos ((listof ico?) (or/c path-string? output-port?) - . -> . void?)] + [replace-icos ((listof ico?) path-string? . -> . void?)] + [replace-all-icos ((listof ico?) path-string? . -> . void?)] [ico->argb (ico? . -> . bytes?)] + [ico->png-bytes (ico? . -> . bytes?)] [argb->ico ([(integer-in 1 256) (integer-in 1 256) bytes? ] [#:depth (one-of/c 1 2 4 8 24 32)] . ->* . - ico?)])) + ico?)] + [png-bytes->ico ([bytes?] + [] + . ->* . + ico?)])) ;; parse-ico build-ico @@ -46,107 +53,21 @@ (define (integer->3/2word i p) (display (subbytes (integer->integer-bytes i 4 #f #f) 0 3) p)) -(define (flag v) - (positive? (bitwise-and #x80000000 v))) -(define (value v) - (bitwise-and #x7FFFFFFF v)) - -(define (skip-to-image-headers-after-signature p) - ;; p is expected to be a file port - (file-position p 60) - (let ([pos (word->integer p)]) - ;; pos points to IMAGE_NT_HEADERS - (file-position p pos) - (unless (= #x4550 (dword->integer p)) - (error "bad signature")) - pos)) - -(define (get-image-base p) - (let ([pos (skip-to-image-headers-after-signature p)]) - (file-position p (+ 4 - 20 - 28)) - (dword->integer p))) - -(define (find-section p find-name) - (let ([pos (skip-to-image-headers-after-signature p)]) - (word->integer p) ; skip machine - (let ([num-sections (word->integer p)] - [_ (begin (dword->integer p) - (dword->integer p) - (dword->integer p))] - [size (word->integer p)]) - (let ([pos (+ pos - 4 ; Signature : DWORD - 20 ; FileHeader: IMAGE_FILE_HEADER - size)]) ; "optional" header - (let sloop ([section 0][section-pos pos]) - (if (= section num-sections) - (error 'find-section "can't find section: ~e" find-name) - (begin - (file-position p section-pos) - ;; p points to an IMAGE_SECTION_HEADER - (let ([name (read-bytes 8 p)]) - (if (bytes=? find-name name) - (let ([_ (dword->integer p)]) ; skip - (values (dword->integer p) ; virtual address - (dword->integer p) ; length - (dword->integer p))); file pos - (sloop (add1 section) (+ section-pos 40))))))))))) - -(define (find-rsrc-start p re:rsrc) - (let-values ([(rsrc-virtual-addr rsrc-len rsrc-pos) - (find-section p #".rsrc\0\0\0")]) - (let loop ([dir-pos 0][path ""]) - (file-position p (+ rsrc-pos dir-pos 12)) - (let ([num-named (word->integer p)] - [num-ided (word->integer p)]) - (let iloop ([i 0]) - (if (= i (+ num-ided num-named)) - #f - (let ([name-delta (dword->integer p)] - [data-delta (dword->integer p)] - [next (file-position p)]) - (or (let ([name (if (flag name-delta) - (begin - (file-position p (+ rsrc-pos (value name-delta))) - (let* ([len (word->integer p)]) - ;; len is in unicode chars... - (let ([unistr (read-bytes (* 2 len) p)]) - ;; Assume it fits into ASCII... - (regexp-replace* "\0" - (bytes->string/latin-1 unistr) - "")))) - (value name-delta))]) - ;;(printf "Name: ~a~a = ~a\n" path name (+ rsrc-pos (value data-delta))) - (let ([full-name (format "~a~a" path name)]) - (if (flag data-delta) - (loop (value data-delta) (string-append full-name ".")) - ;; Found the icon? - (and (regexp-match re:rsrc full-name) - ;; Yes, so read IMAGE_RESOURCE_DATA_ENTRY - (begin - (file-position p (+ rsrc-pos (value data-delta))) - (cons - (+ (dword->integer p) ; offset (an RVA) - (- rsrc-pos - rsrc-virtual-addr)) - (dword->integer p))))))) ; size - (begin - (file-position p next) - (iloop (add1 i))))))))))) - (define-struct ico (desc data) #:mutable) ;; desc is (list width height colors 0 planes bitcount) ;; data is (cons pos bytes) (define (ico-width i) (let ([v (car (ico-desc i))]) (if (= v 0) - 256 + (if (eq? (ico-format i) 'bmp) + 256 + (ico-png-width i)) v))) (define (ico-height i) (let ([v (cadr (ico-desc i))]) (if (= v 0) - 256 + (if (eq? (ico-format i) 'bmp) + 256 + (ico-png-height i)) v))) (define (ico-depth i) (let ([cols (caddr (ico-desc i))]) @@ -155,6 +76,26 @@ (integer-length (sub1 cols))))) (define (ico-colors i) (num-colors (ico-desc i))) +(define (ico-format i) + (define bstr (cdr (ico-data i))) + (define tag (subbytes bstr 0 2)) + (cond + [(and ((bytes-length bstr) . > . 4) + (equal? (subbytes bstr 0 4) #"\211PNG")) + 'png] + [else + ;; Asume BMP + 'bmp])) + +(define (ico-png-width i) + (png-width (cdr (ico-data i)))) +(define (png-width bstr) + (integer-bytes->integer (subbytes bstr 16 20) #f #t)) +(define (ico-png-height i) + (png-height (cdr (ico-data i)))) +(define (png-height bstr) + (integer-bytes->integer (subbytes bstr 20 24) #f #t)) + (define (num-colors l) (let ([n (caddr l)]) (if (zero? n) @@ -173,8 +114,8 @@ (ormap (lambda (ico-ico) (let ([le (ico-desc exe-ico)] [li (ico-desc ico-ico)]) - (and (= (car li) (car le)) - (= (cadr li) (cadr le)) + (and (= (ico-width exe-ico) (ico-width ico-ico)) + (= (ico-height exe-ico) (ico-height ico-ico)) (= (num-colors li) (num-colors le)) (= (bytes-length (cdr (ico-data exe-ico))) (bytes-length (cdr (ico-data ico-ico)))) @@ -185,8 +126,8 @@ ;; need a 16x16, 32x32, or 48x48 ;; ico (and - (= (car (ico-desc exe-ico)) - (cadr (ico-desc exe-ico))) + (= (ico-width exe-ico) + (ico-height exe-ico)) (memq (car (ico-desc exe-ico)) '(16 32 48)) (let ([biggest-colorest #f]) @@ -249,16 +190,88 @@ #t)))))))))]) (unless ico-ico (log-error "no icon conversion available to ~a" (ico-desc exe-ico))) (when ico-ico - (file-position p (car (ico-data exe-ico))) + (file-position p (let ([d (car (ico-data exe-ico))]) + (if (vector? d) + (vector-ref d 0) + d))) (display (cdr (ico-data ico-ico)) p))))) exe-icos)) (lambda () (close-output-port p)))))) +(define (replace-all-icos ico-list exe-file) + (define-values (pe rsrcs) + (call-with-input-file* + exe-file + read-pe+resources)) + (define-values (type name language icos file-pos) + (resource-ref/path rsrcs 14 #f #f)) + (define old-icos + (if icos + (get-icos (open-input-bytes icos) rsrcs) + null)) + (define (ico-res-type i) (vector-ref (car (ico-data i)) 1)) + (define (ico-res-name i) (vector-ref (car (ico-data i)) 2)) + (define (ico-res-language i) (vector-ref (car (ico-data i)) 3)) + (define cleaned-rsrcs + (for/fold ([rsrcs rsrcs]) ([old-i (in-list old-icos)]) + (resource-remove rsrcs + (ico-res-type old-i) + (ico-res-name old-i) + (ico-res-language old-i)))) + ;; Replace individual icons where size and depth match + (define-values (new-rsrcs named-icos) + (for/fold ([rsrcs cleaned-rsrcs] [named-icos null]) ([i (in-list ico-list)]) + (define old-i (for/or ([old-i (in-list old-icos)]) + (and (= (ico-width i) (ico-width old-i)) + (= (ico-height i) (ico-height old-i)) + (= (ico-depth i) (ico-depth old-i)) + old-i))) + (define name + (cond + [old-i (ico-res-name old-i)] + [else + ;; Generate next unused id: + (let loop ([id 1]) + (if (resource-ref rsrcs 3 id 1033) + (loop (add1 id)) + id))])) + (values (resource-set rsrcs + 3 + name + 1033 + (cdr (ico-data i))) + (cons (ico (ico-desc i) + (cons (vector #f 4 name 1033) + (cdr (ico-data i)))) + named-icos)))) + ;; Update ico: + (define ready-rsrcs + (resource-set new-rsrcs type name language (make-icos-header named-icos))) + ;; Write new resources: + (update-resources exe-file pe ready-rsrcs)) + +(define (make-icos-header icos) + (define o (open-output-bytes)) + (integer->word 0 o) + (integer->word 1 o) + (integer->word (length icos) o) + (for ([i (in-list icos)]) + (define desc (ico-desc i)) + (write-byte (list-ref desc 0) o) + (write-byte (list-ref desc 1) o) + (write-byte (list-ref desc 2) o) + (write-byte (list-ref desc 3) o) + (integer->word (list-ref desc 4) o) + (integer->word (list-ref desc 5) o) + (integer->dword (bytes-length (cdr (ico-data i))) o) + (integer->word (vector-ref (car (ico-data i)) 2) o)) + (get-output-bytes o)) + ;; ------------------------------ ;; Image parsing ;; ------------------------------ -(define (get-icos file res?) +(define (get-icos file rsrcs) (let ([p (if (input-port? file) file (open-input-file file))]) @@ -282,7 +295,7 @@ (word->integer p) ; planes (word->integer p)) ; bitcount (list (dword->integer p) ; bytes - ((if res? ; where or icon id + ((if rsrcs ; where or icon id word->integer dword->integer) p))) @@ -293,14 +306,16 @@ ico (let ([size (car (ico-data ico))] [where (cadr (ico-data ico))]) - (let ([ico-pos (if res? - ;; last number is icon id: - (car (find-rsrc-start p (regexp (format "^3[.]~a[.]" where)))) - ;; last number is file position: - where)]) - (file-position p ico-pos) - (cons ico-pos - (read-bytes size p))))) + (cond + [rsrcs + (define-values (type name lang bstr file-pos) + (resource-ref/path rsrcs 3 where #f)) + (cons (vector file-pos type name lang) + bstr)] + [else + (file-position p where) + (cons where + (read-bytes size p))]))) ;; If colors, planes, and bitcount are all 0, ;; get the info from the DIB data (let ([desc (ico-desc ico)]) @@ -595,6 +610,8 @@ (cadr image)))) ; list of mask pixels (define (ico->argb ico) + (unless (eq? 'bmp (ico-format ico)) + (error 'ico->argb "icon not in BMP format")) (let* ([image (parse-ico ico)] [pixels (list-ref image 3)] [len (length pixels)] @@ -616,6 +633,11 @@ (bytes-set! bstr (+ 3 (* i 4)) (bitwise-and #xff p)))) bstr)) +(define (ico->png-bytes ico) + (unless (eq? 'png (ico-format ico)) + (error 'ico->argb "icon not in PNG format")) + (cdr (ico-data ico))) + (define (build-ico base-ico image mask check?) (make-ico (ico-desc base-ico) (cons (car (ico-data base-ico)) @@ -625,14 +647,12 @@ (get-icos ico-file #f)) (define (read-icos-from-exe exe-file) - (let ([p (open-input-file exe-file)]) - (dynamic-wind - void - (lambda () - (let ([pos+size (find-rsrc-start p #rx"^14[.]")]) - (file-position p (car pos+size)) - (get-icos p #t))) - (lambda () (close-input-port p))))) + (define-values (pe rsrcs) + (call-with-input-file* + exe-file + read-pe+resources)) + (define icos (resource-ref rsrcs 14 #f #f)) + (get-icos (open-input-bytes icos) rsrcs)) (define (write-header w h depth o) (integer->dword 40 o) ; size @@ -647,6 +667,11 @@ (integer->dword 0 o) ; used (integer->dword 0 o)) ; important +(define (png-bytes->ico bstr) + (define (256+->0 v) (if (v . >= . 256) 0 v)) + (ico (list (256+->0 (png-width bstr)) (256+->0 (png-height bstr)) 0 0 1 32) + (cons #f bstr))) + (define (argb->ico w h argb #:depth [depth 32]) (let ([o (open-output-bytes)]) (write-header w h 32 o) From 96292cdf27a40f03b5edc6e203aa08326082bc46 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 24 Aug 2015 10:14:27 -0600 Subject: [PATCH 098/381] raco exe --ico: replace icon set wholesale Use exactly the icons in the given icon file for the executable, instead of coercing to the sizes and depths already in the executable. --- pkgs/racket-doc/scribblings/raco/exe-api.scrbl | 10 +++++----- racket/collects/compiler/embed.rkt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl index a5a2ce7853..3c908dc7b9 100644 --- a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl @@ -187,11 +187,11 @@ currently supported keys are as follows: @filepath{.icns}) to use for the executable's desktop icon.} @item{@racket['ico] (Windows) : An icon file path (suffix - @filepath{.ico}) to use for the executable's desktop icon; - the executable will have 16x16, 32x32, and 48x48 icons at - 4-bit, 8-bit, and 32-bit (RGBA) depths; the icons are copied - and generated from any 16x16, 32x32, and 48x48 icons in the - @filepath{.ico} file.} + @filepath{.ico}) to use for the executable's desktop icon. + + @history[#:changed "6.2.900.10" @elem{All icons in the + executable are replaced with icons from the file, + instead of setting only certain sizes and depths.}]} @item{@racket['creator] (Mac OS X) : Provides a 4-character string to use as the application signature.} diff --git a/racket/collects/compiler/embed.rkt b/racket/collects/compiler/embed.rkt index 84c787032c..6f39e74d70 100644 --- a/racket/collects/compiler/embed.rkt +++ b/racket/collects/compiler/embed.rkt @@ -1743,7 +1743,7 @@ (let ([m (and (eq? 'windows (system-type)) (assq 'ico aux))]) (when m - (replace-icos (read-icos (cdr m)) dest-exe))) + (replace-all-icos (read-icos (cdr m)) dest-exe))) (let ([m (and (eq? 'windows (system-type)) (assq 'subsystem aux))]) (when m From d16c5c08b6f4d2c981b0b5bf8c428f7abfe59fa2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 24 Aug 2015 10:16:18 -0600 Subject: [PATCH 099/381] Windows: update default icons Includes a 256x256 icon. --- racket/src/worksp/gc2/make.rkt | 10 +- racket/src/worksp/gracket/gracket.ico | Bin 25214 -> 48086 bytes racket/src/worksp/make-icons.rkt | 235 +++++++++++++++++++++++++ racket/src/worksp/mzcom/mzcom.ico | Bin 1398 -> 50809 bytes racket/src/worksp/racket/racket.ico | Bin 25214 -> 51517 bytes racket/src/worksp/starters/mrstart.ico | Bin 25214 -> 48602 bytes racket/src/worksp/starters/mzstart.ico | Bin 25214 -> 53061 bytes 7 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 racket/src/worksp/make-icons.rkt diff --git a/racket/src/worksp/gc2/make.rkt b/racket/src/worksp/gc2/make.rkt index a62b356cf8..057a04584c 100644 --- a/racket/src/worksp/gc2/make.rkt +++ b/racket/src/worksp/gc2/make.rkt @@ -334,15 +334,17 @@ (map (lambda (n) (format "xsrc/~a.obj" n)) srcs)))) (link-dll libracket-objs null null dll "" #f) -(define (check-rc res rc) +(define (check-rc res rc ico) (unless (and (file-exists? res) (>= (file-or-directory-modify-seconds res) - (file-or-directory-modify-seconds rc))) + (file-or-directory-modify-seconds rc)) + (>= (file-or-directory-modify-seconds res) + (file-or-directory-modify-seconds ico))) (system- (string-append "rc /l 0x409 " (format "/fo~a ~a" res rc))))) -(check-rc "racket.res" "../racket/racket.rc") +(check-rc "racket.res" "../racket/racket.rc" "../racket/racket.ico") (define (link-exe objs libs exe subsystem-flags) (link-dll (append objs (if use-libracket-dll? @@ -387,7 +389,7 @@ #f #t) -(check-rc "gracket.res" "../gracket/gracket.rc") +(check-rc "gracket.res" "../gracket/gracket.rc" "../gracket/gracket.ico") (link-exe (list "gracket.res" diff --git a/racket/src/worksp/gracket/gracket.ico b/racket/src/worksp/gracket/gracket.ico index 91ab991ce0fd7483e7ce6003b11d0d6639130711..22a52b1b7c4182ca5b0aebf089c726a174391131 100644 GIT binary patch literal 48086 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

-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 diff --git a/racket/src/worksp/make-icons.rkt b/racket/src/worksp/make-icons.rkt new file mode 100644 index 0000000000..9369fee39d --- /dev/null +++ b/racket/src/worksp/make-icons.rkt @@ -0,0 +1,235 @@ +#lang racket/base +(require racket/class + racket/draw + racket/math + file/ico + images/icons/style + images/flomap) + +;; ---------------------------------------- +;; The logo code from the manual + +(define (brush c) + (define (l v) (min 255 (floor (* #e1.1 v)))) + (define (d v) (floor (* #e0.8 v))) + (define darker (make-color (d (send c red)) + (d (send c green)) + (d (send c blue)))) + (define much-darker (make-color (d (send darker red)) + (d (send darker green)) + (d (send darker blue)))) + (new brush% [gradient (make-object radial-gradient% + 230 230 250 + 230 230 400 + (list (list 0.0 darker) + (list 1.0 much-darker)))])) + + +(define red-brush (brush (make-object color% 255 36 32))) +(define blue-brush (brush (make-object color% 32 36 255))) + +(define left-lambda-path + (let ([p (new dc-path%)]) + (send p move-to 153 44) + (send p line-to 161.5 60) + (send p curve-to 202.5 49 230 42 245 61) + (send p curve-to 280.06 105.41 287.5 141 296.5 186) + (send p curve-to 301.12 209.08 299.11 223.38 293.96 244) + (send p curve-to 281.34 294.54 259.18 331.61 233.5 375) + (send p curve-to 198.21 434.63 164.68 505.6 125.5 564) + (send p line-to 135 572) + p)) + +(define left-logo-path + (let ([p (new dc-path%)]) + (send p append left-lambda-path) + (send p arc 0 0 630 630 (* 47/72 2 pi) (* 121/360 2 pi) #f) + p)) + +(define bottom-lambda-path + (let ([p (new dc-path%)]) + (send p move-to 135 572) + (send p line-to 188.5 564) + (send p curve-to 208.5 517 230.91 465.21 251 420) + (send p curve-to 267 384 278.5 348 296.5 312) + (send p curve-to 301.01 302.98 318 258 329 274) + (send p curve-to 338.89 288.39 351 314 358 332) + (send p curve-to 377.28 381.58 395.57 429.61 414 477) + (send p curve-to 428 513 436.5 540 449.5 573) + (send p line-to 465 580) + (send p line-to 529 545) + p)) + +(define bottom-logo-path + (let ([p (new dc-path%)]) + (send p append bottom-lambda-path) + (send p arc 0 0 630 630 (* 157/180 2 pi) (* 47/72 2 pi) #f) + p)) + +(define right-lambda-path + (let ([p (new dc-path%)]) + (send p move-to 153 44) + (send p curve-to 192.21 30.69 233.21 14.23 275 20) + (send p curve-to 328.6 27.4 350.23 103.08 364 151) + (send p curve-to 378.75 202.32 400.5 244 418 294) + (send p curve-to 446.56 375.6 494.5 456 530.5 537) + (send p line-to 529 545) + p)) + +(define right-logo-path + (let ([p (new dc-path%)]) + (send p append right-lambda-path) + (send p arc 0 0 630 630 (* 157/180 2 pi) (* 121/360 2 pi) #t) + p)) + +(define lambda-path + (let ([p (new dc-path%)]) + (send p append left-lambda-path) + (send p append bottom-lambda-path) + (let ([t (new dc-path%)]) + (send t append right-lambda-path) + (send t reverse) + (send p append t)) + (send p close) + p)) + +(define (paint-racket dc) + (send dc set-pen "black" 0 'transparent) + (send dc set-brush "white" 'solid) + (send dc draw-path lambda-path) + + (send dc set-pen "black" 4 'solid) + + (send dc set-brush red-brush) + (send dc draw-path left-logo-path) + (send dc draw-path bottom-logo-path) + + (send dc set-brush blue-brush) + (send dc draw-path right-logo-path)) + +(define (draw dc) + (send dc scale (/ 265 170) (/ 256 170)) + (send dc translate 3 6) + (send dc scale 0.25 0.25) + (paint-racket dc)) + +(define (go [scale 1]) + (define racket-logo (make-bitmap (* scale 256) (* scale 256))) + (define dc (new bitmap-dc% [bitmap racket-logo])) + + (send dc scale scale scale) + (send dc set-smoothing 'smoothed) + + (draw dc) + + racket-logo) + +;; -------------------------------------------------------------------------------- + +(define (scale-bm sz bm) + (define bm2 (make-platform-bitmap sz sz)) + (define dc (send bm2 make-dc)) + (send dc scale (/ sz (send bm get-width)) (/ sz (send bm get-height))) + (send dc set-smoothing 'smoothed) + (send dc draw-bitmap bm 0 0) + bm2) + +(define (maybe-render-icon bm) + (scale-bm + 256 + (if #f + (bitmap-render-icon bm 0 plastic-icon-material) + bm))) + +; (define logo-bm (render-icon (go 2))) +; (define logo-bm (go)) +(define logo-bm (read-bitmap (collection-file-path "plt-logo-red-diffuse.png" "icons"))) + +(define cmdline-bm + (let ([bm (make-platform-bitmap 256 256)]) + (define dc (send bm make-dc)) + (send dc set-brush (new brush% + [gradient + (make-object linear-gradient% + 0 0 100 256 + (list (list 0.0 (make-color 250 250 250)) + (list 1.0 (make-color 220 220 220))))])) + (send dc set-pen (make-pen #:color "gray" #:width 4)) + (send dc draw-rectangle 2 24 252 208) + (send dc set-pen (make-pen #:style 'transparent)) + (send dc set-smoothing 'smoothed) + (send dc set-font (make-font #:size 64 #:size-in-pixels? #t #:weight 'bold #:family 'modern)) + (send dc set-text-foreground "black") + (define-values (w h d a) (send dc get-text-extent ">")) + (send dc draw-text ">" 14 32) + (define s 0.65) + (send dc scale s s) + (send dc draw-bitmap logo-bm (* s 45/100 256) (* s 40/100 256)) + bm)) + +(define com-bm + (let ([bm (make-platform-bitmap 256 256)]) + (define dc (send bm make-dc)) + (send dc draw-bitmap logo-bm 0 0) + (send dc set-font (make-font #:face "Courier New" #:weight 'bold #:size 96)) + (define-values (w h d a) (send dc get-text-extent "COM")) + (send dc set-text-foreground "white") + (send dc set-brush (make-brush #:color (make-color 0 0 0 0.25))) + (send dc set-pen (make-pen #:style 'transparent)) + (define x (/ (- 256 w) 2)) + (define y (- 256 h)) + (send dc draw-rectangle (- x 20) (+ a y) (+ w 40) (- h a (/ d 2))) + (send dc draw-text "COM" x y) + bm)) + +(define starter-bm + (maybe-render-icon + (let ([bm (make-platform-bitmap 512 512)]) + (define dc (send bm make-dc)) + (send dc scale 2 2) + (send dc set-smoothing 'smoothed) + (send dc set-pen (make-pen #:style 'transparent)) + (send dc set-brush (make-color 40 200 40) 'solid) + (define x 156) + (define y 156) + (send dc draw-ellipse x y 100 100) + (send dc set-pen (make-pen #:cap 'round #:width 10 #:color "white")) + (send dc draw-line (+ x 20) (+ y 50) (+ x 80) (+ y 50)) + (send dc draw-line (+ x 60) (+ y 35) (+ x 80) (+ y 50)) + (send dc draw-line (+ x 60) (+ y 65) (+ x 80) (+ y 50)) + bm))) + +(define (add-starter-arrow orig-bm) + (let ([bm (make-platform-bitmap 256 256)]) + (define dc (send bm make-dc)) + (send dc draw-bitmap orig-bm 0 0) + (send dc draw-bitmap starter-bm 0 0) + bm)) + +(define (generate dest bm) + (define (make-ico sz) + (define bm2 (scale-bm sz bm)) + (define bstr (make-bytes (* 4 sz sz))) + (send bm2 get-argb-pixels 0 0 sz sz bstr) + (argb->ico sz sz bstr)) + + (define o (open-output-bytes)) + (send bm save-file o 'png) + (define png-bytes (get-output-bytes o)) + + (when (file-exists? dest) + (delete-file dest)) + + (write-icos + (cons + (png-bytes->ico png-bytes) + (for/list ([sz '(16 32 48)]) + (make-ico sz))) + dest)) + +(generate "gracket/gracket.ico" logo-bm) +(generate "racket/racket.ico" cmdline-bm) +(generate "mzcom/mzcom.ico" com-bm) +(generate "starters/mrstart.ico" (add-starter-arrow logo-bm)) +(generate "starters/mzstart.ico" (add-starter-arrow cmdline-bm)) + diff --git a/racket/src/worksp/mzcom/mzcom.ico b/racket/src/worksp/mzcom/mzcom.ico index 0538a644806368750522407fc1c7be5266d732e8..6ec82afed3005ff240eaab333e7b34cc1cb78de4 100644 GIT binary patch literal 50809 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 I?&t9T0BmzANB{r; literal 1398 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 NpTFUOFZq>S|DOSb=<@&o literal 25214 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 diff --git a/racket/src/worksp/starters/mzstart.ico b/racket/src/worksp/starters/mzstart.ico index 87710beacea313c853fc46a5a149fb5268f8f776..795b6c2b39795b9caf4572d68ae00bd3e9b1a98f 100644 GIT binary patch literal 53061 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 From 3d452fdba674797996d05b84adbd750175716847 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 24 Aug 2015 13:29:48 -0600 Subject: [PATCH 100/381] raco exe: make Windows exes as proper PE32 images Instead of simply tacking bytecode onto the end of an executable, generate a proper PE32 image. --- .../scribblings/reference/startup.scrbl | 3 +- racket/collects/compiler/embed.rkt | 121 +++++++++------ racket/src/racket/cmdline.inc | 145 ++++++++++++++++-- 3 files changed, 207 insertions(+), 62 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/startup.scrbl b/pkgs/racket-doc/scribblings/reference/startup.scrbl index f9a3a89de6..564d69cccb 100644 --- a/pkgs/racket-doc/scribblings/reference/startup.scrbl +++ b/pkgs/racket-doc/scribblings/reference/startup.scrbl @@ -177,7 +177,8 @@ flags: embedded in the executable from file position @nonterm{n} to @nonterm{m} and from @nonterm{m} to @nonterm{p}. (On Mac OS X, @nonterm{n}, @nonterm{m}, and @nonterm{p} are relative to a - @tt{__PLTSCHEME} segment in the executable.) The first range + @tt{__PLTSCHEME} segment in the executable. On Windows, + they are relative to a resource of type 257 and ID 1.) The first range is loaded in every new @tech{place}, and any modules declared in that range are considered predefined in the sense of @racket[module-predefined?]. This option is normally embedded diff --git a/racket/collects/compiler/embed.rkt b/racket/collects/compiler/embed.rkt index 6f39e74d70..5bf8add8f4 100644 --- a/racket/collects/compiler/embed.rkt +++ b/racket/collects/compiler/embed.rkt @@ -17,6 +17,7 @@ "private/mach-o.rkt" "private/elf.rkt" "private/windlldir.rkt" + "private/pe-rsrc.rkt" "private/collects-path.rkt" "private/configdir.rkt" "find-exe.rkt") @@ -1582,54 +1583,76 @@ full-cmdline) (display "\0\0\0\0" out))]) (let-values ([(start decl-end end cmdline-end) - (if (and (eq? (system-type) 'macosx) - (not unix-starter?)) - ;; For Mach-O, we know how to add a proper segment - (let ([s (open-output-bytes)]) - (define decl-len (write-module s)) - (let* ([s (get-output-bytes s)] - [cl (let ([o (open-output-bytes)]) - ;; position is relative to __PLTSCHEME: - (write-cmdline (make-full-cmdline 0 decl-len (bytes-length s)) o) - (get-output-bytes o))]) - (let ([start (add-plt-segment - dest-exe - (bytes-append - s - cl))]) - (let ([start 0]) ; i.e., relative to __PLTSCHEME - (values start - (+ start decl-len) - (+ start (bytes-length s)) - (+ start (bytes-length s) (bytes-length cl))))))) - ;; Unix starter: Maybe ELF, in which case we - ;; can add a proper section - (let-values ([(s e dl p) - (if unix-starter? - (add-racket-section - orig-exe - dest-exe - (if launcher? #".rackcmdl" #".rackprog") - (lambda (start) - (let ([s (open-output-bytes)]) - (define decl-len (write-module s)) - (let ([p (file-position s)]) - (display (make-starter-cmdline - (make-full-cmdline start - (+ start decl-len) - (+ start p))) - s) - (values (get-output-bytes s) decl-len p))))) - (values #f #f #f #f))]) - (if (and s e) - ;; ELF succeeded: - (values s (+ s dl) (+ s p) e) - ;; Otherwise, just add to the end of the file: - (let ([start (file-size dest-exe)]) - (define decl-end - (call-with-output-file* dest-exe write-module - #:exists 'append)) - (values start decl-end (file-size dest-exe) #f)))))]) + (cond + [(eq? (system-type) 'windows) + ;; Add as a resource + (define o (open-output-bytes)) + (define decl-len (write-module o)) + (define init-len (bytes-length (get-output-bytes o))) + (write-cmdline (make-full-cmdline 0 decl-len init-len) o) + (define bstr (get-output-bytes o)) + (define cmdline-len (- (bytes-length bstr) init-len)) + (define-values (pe rsrcs) (call-with-input-file* + dest-exe + read-pe+resources)) + (define new-rsrcs (resource-set rsrcs + ;; Racket's "user-defined" type for excutable + ;; plus command line: + 257 + 1 + 1033 ; U.S. English + bstr)) + (update-resources dest-exe pe new-rsrcs) + (values 0 decl-len init-len (+ init-len cmdline-len))] + [(and (eq? (system-type) 'macosx) + (not unix-starter?)) + ;; For Mach-O, we know how to add a proper segment + (define s (open-output-bytes)) + (define decl-len (write-module s)) + (let* ([s (get-output-bytes s)] + [cl (let ([o (open-output-bytes)]) + ;; position is relative to __PLTSCHEME: + (write-cmdline (make-full-cmdline 0 decl-len (bytes-length s)) o) + (get-output-bytes o))]) + (let ([start (add-plt-segment + dest-exe + (bytes-append + s + cl))]) + (let ([start 0]) ; i.e., relative to __PLTSCHEME + (values start + (+ start decl-len) + (+ start (bytes-length s)) + (+ start (bytes-length s) (bytes-length cl))))))] + [else + ;; Unix starter: Maybe ELF, in which case we + ;; can add a proper section + (define-values (s e dl p) + (if unix-starter? + (add-racket-section + orig-exe + dest-exe + (if launcher? #".rackcmdl" #".rackprog") + (lambda (start) + (let ([s (open-output-bytes)]) + (define decl-len (write-module s)) + (let ([p (file-position s)]) + (display (make-starter-cmdline + (make-full-cmdline start + (+ start decl-len) + (+ start p))) + s) + (values (get-output-bytes s) decl-len p))))) + (values #f #f #f #f))) + (if (and s e) + ;; ELF succeeded: + (values s (+ s dl) (+ s p) e) + ;; Otherwise, just add to the end of the file: + (let ([start (file-size dest-exe)]) + (define decl-end + (call-with-output-file* dest-exe write-module + #:exists 'append)) + (values start decl-end (file-size dest-exe) #f)))])]) (when unix-starter? (adjust-config-dir)) (when verbose? @@ -1729,7 +1752,7 @@ (unless cmdline-done? (write-cmdline full-cmdline out)) (when long-cmdline? - ;; cmdline written at the end; + ;; cmdline written at the end, in a resource, etc.; ;; now put forwarding information at the normal cmdline pos (let ([new-end (or cmdline-end (file-position out))]) diff --git a/racket/src/racket/cmdline.inc b/racket/src/racket/cmdline.inc index c1e8d54ee4..520b641102 100644 --- a/racket/src/racket/cmdline.inc +++ b/racket/src/racket/cmdline.inc @@ -136,6 +136,126 @@ static long get_segment_offset() } #endif +#ifdef DOS_FILE_SYSTEM +wchar_t *get_self_executable_path() +{ + wchar_t *path; + DWORD r, sz = 1024; + + while (1) { + path = (wchar_t *)malloc(sz * sizeof(wchar_t)); + r = GetModuleFileNameW(NULL, path, sz); + if ((r == sz) + && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { + free(path); + sz = 2 * sz; + } else + break; + } + + return path; +} + +static DWORD find_by_id(HANDLE fd, DWORD rsrcs, DWORD pos, int id) +{ + DWORD got, val; + WORD name_count, id_count, i; + + SetFilePointer(fd, pos + 12, 0, FILE_BEGIN); + ReadFile(fd, &name_count, 2, &got, NULL); + ReadFile(fd, &id_count, 2, &got, NULL); + + pos += 16 + (name_count * 8); + while (id_count--) { + ReadFile(fd, &val, 4, &got, NULL); + if (val == id) { + ReadFile(fd, &val, 4, &got, NULL); + return rsrcs + (val & 0x7FFFFFF); + } else { + ReadFile(fd, &val, 4, &got, NULL); + } + } + + return 0; +} + +static long get_segment_offset() +{ + /* Find the resource of type 257 */ + wchar_t *path; + HANDLE fd; + + path = get_self_executable_path(); + fd = CreateFileW(path, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL); + free(path); + + if (fd == INVALID_HANDLE_VALUE) + return 0; + else { + DWORD val, got, sec_pos, virtual_addr, rsrcs, pos; + WORD num_sections, head_size; + char name[8]; + + SetFilePointer(fd, 60, 0, FILE_BEGIN); + ReadFile(fd, &val, 4, &got, NULL); + SetFilePointer(fd, val+4+2, 0, FILE_BEGIN); /* Skip "PE\0\0" tag and machine */ + ReadFile(fd, &num_sections, 2, &got, NULL); + SetFilePointer(fd, 12, 0, FILE_CURRENT); /* time stamp + symbol table */ + ReadFile(fd, &head_size, 2, &got, NULL); + + sec_pos = val+4+20+head_size; + while (num_sections--) { + SetFilePointer(fd, sec_pos, 0, FILE_BEGIN); + ReadFile(fd, &name, 8, &got, NULL); + if ((name[0] == '.') + && (name[1] == 'r') + && (name[2] == 's') + && (name[3] == 'r') + && (name[4] == 'c') + && (name[5] == 0)) { + SetFilePointer(fd, 4, 0, FILE_CURRENT); /* skip virtual size */ + ReadFile(fd, &virtual_addr, 4, &got, NULL); + SetFilePointer(fd, 4, 0, FILE_CURRENT); /* skip file size */ + ReadFile(fd, &rsrcs, 4, &got, NULL); + SetFilePointer(fd, rsrcs, 0, FILE_BEGIN); + + /* We're at the resource table; step through 3 layers */ + pos = find_by_id(fd, rsrcs, rsrcs, 257); + if (pos) { + pos = find_by_id(fd, rsrcs, pos, 1); + if (pos) { + pos = find_by_id(fd, rsrcs, pos, 1033); + + if (pos) { + /* pos is the reource data entry */ + SetFilePointer(fd, pos, 0, FILE_BEGIN); + ReadFile(fd, &val, 4, &got, NULL); + pos = val - virtual_addr + rsrcs; + + CloseHandle(fd); + + return pos; + } + } + } + + break; + } + sec_pos += 40; + } + + /* something went wrong */ + CloseHandle(fd); + return 0; + } +} +#endif + #ifndef DONT_PARSE_COMMAND_LINE static int is_number_arg(const char *s) { @@ -159,7 +279,7 @@ static int is_number_arg(const char *s) return 1; } -#ifdef OS_X +#if defined(OS_X) || defined(DOS_FILE_SYSTEM) char *add_to_str(const char *addr, long amt) { long addr_v; @@ -175,7 +295,7 @@ static char *make_embedded_load(const char *start, const char *end) char *s; int slen, elen; -#ifdef OS_X +#if defined(OS_X) || defined(DOS_FILE_SYSTEM) { long fileoff; fileoff = get_segment_offset(); @@ -844,17 +964,16 @@ static int run_from_cmd_line(int argc, char *_argv[], #ifdef DOS_FILE_SYSTEM if ((scheme_cmdline_exe_hack[0] == '?') || (scheme_cmdline_exe_hack[0] == '*')) { - /* This is how we make launchers in Windows. - The cmdline is appended to the end of the binary. - The long integer at scheme_cmdline_exe_hack[4] says - where the old end was, and scheme_cmdline_exe_hack[8] - says how long the cmdline string is. It might - be relative to the executable. */ - wchar_t *path; + /* This is how we make launchers in Windows. The cmdline is + added as a resource of type 257. The long integer at + scheme_cmdline_exe_hack[4] says where the command line starts + with the source, and scheme_cmdline_exe_hack[8] says how long + the cmdline string is. It might be relative to the + executable. */ HANDLE fd; + wchar_t *path; - path = (wchar_t *)malloc(1024 * sizeof(wchar_t)); - GetModuleFileNameW(NULL, path, 1024); + path = get_self_executable_path(); fd = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, @@ -868,6 +987,7 @@ static int run_from_cmd_line(int argc, char *_argv[], DWORD got; start = *(long *)&scheme_cmdline_exe_hack[4]; len = *(long *)&scheme_cmdline_exe_hack[8]; + start += get_segment_offset(); p = (unsigned char *)malloc(len); SetFilePointer(fd, start, 0, FILE_BEGIN); ReadFile(fd, p, len, &got, NULL); @@ -916,9 +1036,10 @@ static int run_from_cmd_line(int argc, char *_argv[], + 4); } } + free(path); } #endif -#ifdef OS_X +#if defined(OS_X) if (scheme_cmdline_exe_hack[0] == '?') { long fileoff, cmdoff, cmdlen; int fd; From a1e6c94fda64504138b20d1d0edbe902b3a2abe1 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 25 Aug 2015 05:08:24 -0500 Subject: [PATCH 101/381] lift a few fewer negative parties --- racket/collects/racket/contract/private/provide.rkt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index 3d2982e1d1..d874ae1acd 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -92,9 +92,10 @@ (define (contract-neg-party-property stx) (syntax-property stx neg-party-key)) + (define global-saved-id-table (make-hasheq)) + (struct provide/contract-arrow-transformer provide/contract-info - (saved-id-table - saved-ho-id-table + (saved-ho-id-table partially-applied-id extra-neg-party-argument-fn valid-argument-lists) @@ -102,7 +103,6 @@ prop:set!-transformer (λ (self stx) (let ([partially-applied-id (provide/contract-arrow-transformer-partially-applied-id self)] - [saved-id-table (provide/contract-arrow-transformer-saved-id-table self)] [saved-ho-id-table (provide/contract-arrow-transformer-saved-ho-id-table self)] [extra-neg-party-argument-fn (provide/contract-arrow-transformer-extra-neg-party-argument-fn self)] @@ -115,12 +115,12 @@ (let* ([key (syntax-local-lift-context)] ;; Already lifted in this lifting context? [lifted-neg-party - (or (hash-ref saved-id-table key #f) + (or (hash-ref global-saved-id-table key #f) ;; No: lift the neg name creation (syntax-local-introduce (syntax-local-lift-expression #'(quote-module-name))))]) - (when key (hash-set! saved-id-table key lifted-neg-party)) + (when key (hash-set! global-saved-id-table key lifted-neg-party)) ;; Expand to a use of the lifted expression: (define (adjust-location new-stx) (datum->syntax new-stx (syntax-e new-stx) stx new-stx)) @@ -161,7 +161,6 @@ ;; expressions: (quasisyntax/loc stx (#%expression #,stx))))))) - (struct provide/contract-transformer provide/contract-info (saved-id-table partially-applied-id) #:property prop:set!-transformer @@ -222,7 +221,7 @@ (define (make-provide/contract-arrow-transformer rename-id contract-id id pai enpfn val) (provide/contract-arrow-transformer rename-id contract-id id - (make-hasheq) (make-hasheq) + (make-hasheq) pai enpfn val))) From d86ccb13306f9c11af43c6bef5a1efb86b6312c1 Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Mon, 24 Aug 2015 21:41:40 -0600 Subject: [PATCH 102/381] initializing ui->closures in the right place --- racket/src/racket/src/resolve.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 4f83e2c75c..ee46cc00cc 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -3261,6 +3261,8 @@ static Unresolve_Info *new_unresolve_info(Scheme_Prefix *prefix) ui->definitions = scheme_null; ht = scheme_make_hash_table(SCHEME_hash_ptr); ui->ref_lifts = ht; + ht = scheme_make_hash_table(SCHEME_hash_ptr); + ui->closures = ht; return ui; } @@ -3964,7 +3966,6 @@ Scheme_Object *unresolve_module(Scheme_Object *e, Unresolve_Info *ui) { Scheme_Module *m = (Scheme_Module *)e, *nm; Scheme_Object *dummy, *bs, *bs2, *ds, **bss; - Scheme_Hash_Table *ht; Comp_Prefix *cp; int i, cnt, len; @@ -3976,8 +3977,6 @@ Scheme_Object *unresolve_module(Scheme_Object *e, Unresolve_Info *ui) cnt = SCHEME_VEC_SIZE(m->bodies[0]); bs = scheme_make_vector(cnt, NULL); - ht = scheme_make_hash_table(SCHEME_hash_ptr); - ui->closures = ht; for (i = 0; i < cnt; i++) { locate_cyclic_closures(SCHEME_VEC_ELS(m->bodies[0])[i], ui); } From fadcb78ffa719f84453e36d99db2b9cd20ddddce Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 18 Aug 2015 21:12:07 -0400 Subject: [PATCH 103/381] Fixes to prop:rename-transformer The error message for the guard used an incorrect contract. Also removed an unused line that allows a box value in the property. I don't think it was possible to trigger this line anyway because of the dynamic check. --- racket/src/racket/src/struct.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index 958ce74892..a99eccc902 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -1875,7 +1875,6 @@ Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o) if (SCHEME_CHAPERONE_STRUCTP(o)) { Scheme_Object *v; v = scheme_struct_type_property_ref(rename_transformer_property, o); - if (SCHEME_BOXP(v)) v = SCHEME_BOX_VAL(v); if (SCHEME_INTP(v)) { v = scheme_struct_ref(o, SCHEME_INT_VAL(v)); if (!is_stx_id(v)) { @@ -1891,7 +1890,7 @@ static Scheme_Object *check_rename_transformer_property_value_ok(int argc, Schem { return check_indirect_property_value_ok("guard-for-prop:rename-transformer", is_stx_id, 0, - "(or/c exact-nonnegative-integer? (boxof exact-nonnegative-integer?))", + "(or/c exact-nonnegative-integer? identifier?)", argc, argv); } From ba7e2f11ecc0f90e688984e0e05ef8b6b618db43 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 25 Aug 2015 16:43:56 -0600 Subject: [PATCH 104/381] repair MinGW32 builds Also, change floating-point handling to be like the MSVC build by default, where the process is left in double-precision mode and the mode is changed for exfl operations. Includes repairs for integer-size mismatches in uses of Windows threads. --- racket/src/README | 7 -- racket/src/foreign/foreign.c | 8 +-- racket/src/foreign/foreign.rktc | 8 +-- racket/src/racket/Makefile.in | 7 ++ racket/src/racket/cmdline.inc | 2 +- racket/src/racket/gc2/Makefile.in | 8 ++- racket/src/racket/include/scheme.h | 2 +- racket/src/racket/sconfig.h | 16 +++-- racket/src/racket/src/longdouble/longdouble.c | 2 +- racket/src/racket/src/longdouble/longdouble.h | 10 ++- racket/src/racket/src/mzrt.c | 31 ++++++--- racket/src/racket/src/mzrt.h | 9 ++- racket/src/racket/src/mzsj86g.S | 67 +++++++++++++++++-- racket/src/racket/src/network.c | 12 +++- racket/src/racket/src/setjmpup.c | 22 ++++++ racket/src/worksp/gracket/gracket.rc | 9 +++ racket/src/worksp/racket/racket.rc | 9 +++ 17 files changed, 180 insertions(+), 49 deletions(-) diff --git a/racket/src/README b/racket/src/README index 93323f5d56..7b3d953b0e 100644 --- a/racket/src/README +++ b/racket/src/README @@ -36,13 +36,6 @@ result is a Unix-style build, not a Windows-style build (e.g., Racket's `system-type' procedure returns 'unix, not 'windows, and `racket/gui' uses Gtk instead of Win32). -Beware that MinGW/Cygwin builds different from the MSVC build when -SSE-based floating-point math is enabled in the C compiler. In that -case, Racket includes sets the floating-point mode to extended -precision to support extflonums, and changing precision may affect -other libraries. To avoid the floating-point mode change, disable -extflonum support with `--disable-extflonum'. - ======================================================================== Compiling for Mac OS X ======================================================================== diff --git a/racket/src/foreign/foreign.c b/racket/src/foreign/foreign.c index 1bf1c897dd..28657f947a 100644 --- a/racket/src/foreign/foreign.c +++ b/racket/src/foreign/foreign.c @@ -3877,7 +3877,7 @@ typedef struct Queued_Callback { typedef struct FFI_Sync_Queue { Queued_Callback *callbacks; /* malloc()ed list */ mzrt_mutex *lock; - mzrt_thread_id orig_thread; + mzrt_os_thread_id orig_thread; void *sig_hand; } FFI_Sync_Queue; @@ -3987,7 +3987,7 @@ static void ffi_queue_callback(ffi_cif* cif, void* resultp, void** args, void *u queue = (FFI_Sync_Queue *)(data)[1]; userdata = (data)[0]; - if (queue->orig_thread != mz_proc_thread_self()) { + if (queue->orig_thread != mz_proc_os_thread_self()) { if (data[2]) { /* constant result */ memcpy(resultp, data[2], (intptr_t)data[3]); @@ -4141,11 +4141,11 @@ static Scheme_Object *foreign_ffi_callback(int argc, Scheme_Object *argv[]) if (((argc > 5) && SCHEME_TRUEP(argv[5]))) { # ifdef MZ_USE_MZRT if (!ffi_sync_queue) { - mzrt_thread_id tid; + mzrt_os_thread_id tid; void *sig_hand; ffi_sync_queue = (FFI_Sync_Queue *)malloc(sizeof(FFI_Sync_Queue)); - tid = mz_proc_thread_self(); + tid = mz_proc_os_thread_self(); ffi_sync_queue->orig_thread = tid; mzrt_mutex_create(&ffi_sync_queue->lock); sig_hand = scheme_get_signal_handle(); diff --git a/racket/src/foreign/foreign.rktc b/racket/src/foreign/foreign.rktc index 22a871fccc..d54571a928 100755 --- a/racket/src/foreign/foreign.rktc +++ b/racket/src/foreign/foreign.rktc @@ -3039,7 +3039,7 @@ typedef struct Queued_Callback { typedef struct FFI_Sync_Queue { Queued_Callback *callbacks; /* malloc()ed list */ mzrt_mutex *lock; - mzrt_thread_id orig_thread; + mzrt_os_thread_id orig_thread; void *sig_hand; } FFI_Sync_Queue; @@ -3149,7 +3149,7 @@ static void ffi_queue_callback(ffi_cif* cif, void* resultp, void** args, void *u queue = (FFI_Sync_Queue *)(data)[1]; userdata = (data)[0]; - if (queue->orig_thread != mz_proc_thread_self()) { + if (queue->orig_thread != mz_proc_os_thread_self()) { if (data[2]) { /* constant result */ memcpy(resultp, data[2], (intptr_t)data[3]); @@ -3301,11 +3301,11 @@ static void free_cl_cif_queue_args(void *ignored, void *p) if (((argc > 5) && SCHEME_TRUEP(argv[5]))) { @@IFDEF{MZ_USE_MZRT}{ if (!ffi_sync_queue) { - mzrt_thread_id tid; + mzrt_os_thread_id tid; void *sig_hand; ffi_sync_queue = (FFI_Sync_Queue *)malloc(sizeof(FFI_Sync_Queue)); - tid = mz_proc_thread_self(); + tid = mz_proc_os_thread_self(); ffi_sync_queue->orig_thread = tid; mzrt_mutex_create(&ffi_sync_queue->lock); sig_hand = scheme_get_signal_handle(); diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 7e1ad7ad1f..d5c7edcca6 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -401,11 +401,16 @@ mingw-install: cd ..; rm -f "$(DESTDIR)@MZINSTALLBINDIR@/racket@MMM_INSTALLED@" cd ..; cp racket/starter@EXE_SUFFIX@ "$(DESTDIR)$(libpltdir)/MzStart@EXE_SUFFIX@" cd ..; cp racket/mrstarter@EXE_SUFFIX@ "$(DESTDIR)$(libpltdir)/MrStart@EXE_SUFFIX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/MzStart@EXE_SUFFIX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/MrStart@EXE_SUFFIX@" mingw-install-cgc: cd ..; $(ICP) racket/lib/libmzgcxxxxxxx.dll "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" cd ..; $(ICP) racket/lib/libracketxxxxxxx.dll "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll" cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" @RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ mingw-install-cgc-final: @@ -414,6 +419,8 @@ mingw-install-cgc-final: mingw-install-3m: cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(ICP) racket/lib/libracket3mxxxxxxx.dll "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll" @RUN_RACKET_MMM@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ mingw-install-3m-final: diff --git a/racket/src/racket/cmdline.inc b/racket/src/racket/cmdline.inc index 520b641102..ddee9ad5c3 100644 --- a/racket/src/racket/cmdline.inc +++ b/racket/src/racket/cmdline.inc @@ -159,7 +159,7 @@ wchar_t *get_self_executable_path() static DWORD find_by_id(HANDLE fd, DWORD rsrcs, DWORD pos, int id) { DWORD got, val; - WORD name_count, id_count, i; + WORD name_count, id_count; SetFilePointer(fd, pos + 12, 0, FILE_BEGIN); ReadFile(fd, &name_count, 2, &got, NULL); diff --git a/racket/src/racket/gc2/Makefile.in b/racket/src/racket/gc2/Makefile.in index ebb58455a1..e2051fd08a 100644 --- a/racket/src/racket/gc2/Makefile.in +++ b/racket/src/racket/gc2/Makefile.in @@ -181,7 +181,11 @@ xsrc: xobjects: $(OBJS) main.@LTO@ -XFORMDEP_NOPRE = $(srcdir)/xform.rkt $(srcdir)/xform-mod.rkt +# These headers have only preprocessor definitions, so they're not +# picked up in ".sdep": +QUIET_DEPS = $(srcdir)/../src/schvers.h $(srcdir)/../sconfig.h ../mzconfig.h + +XFORMDEP_NOPRE = $(srcdir)/xform.rkt $(srcdir)/xform-mod.rkt $(QUIET_DEPS) XFORMDEP = $(XFORMDEP_NOPRE) $(XSRCDIR)/precomp.h MZRTDEP = $(srcdir)/../src/schpriv.h $(srcdir)/../include/scheme.h \ @@ -193,7 +197,7 @@ MZRTDEP = $(srcdir)/../src/schpriv.h $(srcdir)/../include/scheme.h \ check-sdep : @RUN_RACKET_CGC@ $(SELF_RACKET_FLAGS) -cqu $(srcdir)/check-sdep.rkt -$(XSRCDIR)/precomp.h : $(XFORMDEP_NOPRE) $(srcdir)/../src/schvers.h +$(XSRCDIR)/precomp.h : $(XFORMDEP_NOPRE) env XFORM_PRECOMP=yes $(XFORM_NOPRECOMP) $(XSRCDIR)/precomp.h $(srcdir)/precomp.c $(XSRCDIR)/salloc.c: $(XFORMDEP) diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 91a5d30b88..71f7620a31 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -84,7 +84,7 @@ #endif #ifdef MZ_LONG_DOUBLE -# if defined(_MSC_VER) +# ifdef MZ_LONG_DOUBLE_API_IS_EXTERNAL # define BYTES_RESERVED_FOR_LONG_DOUBLE 16 typedef struct { char bytes[BYTES_RESERVED_FOR_LONG_DOUBLE]; diff --git a/racket/src/racket/sconfig.h b/racket/src/racket/sconfig.h index bc26e02c9a..f308a5aa76 100644 --- a/racket/src/racket/sconfig.h +++ b/racket/src/racket/sconfig.h @@ -660,7 +660,7 @@ # define DO_STACK_CHECK # define WINDOWS_FIND_STACK_BOUNDS -# if !defined(_WIN64) || (_MSC_VER >= 1600) +# if !defined(_WIN64) || (_MSC_VER >= 1600) || defined(__MINGW32__) # define USE_MZ_SETJMP # endif @@ -729,14 +729,18 @@ # define IGNORE_BY_BORLAND_CONTROL_87 #endif -#if defined(_MSC_VER) +#if defined(__MINGW32__) && defined(USE_DIRECT_LONG_DOUBLE) +/* Beware: different from the MSVC build when SSE-based floating-point + math is enabled in the C compiler. Sets the floating-point mode to + extended precision to support extflonums, and changing precision + may affect other libraries. */ +# define MZ_TRY_EXTFLONUMS +# define ASM_DBLPREC_CONTROL_87 +#else # define MZ_LONG_DOUBLE # define IGNORE_BY_MS_CONTROL_87 # define MZ_NEED_SET_EXTFL_MODE -#endif -#if defined(__MINGW32__) -# define MZ_TRY_EXTFLONUMS -# define ASM_DBLPREC_CONTROL_87 +# define MZ_LONG_DOUBLE_API_IS_EXTERNAL #endif # define REGISTER_POOR_MACHINE diff --git a/racket/src/racket/src/longdouble/longdouble.c b/racket/src/racket/src/longdouble/longdouble.c index 99dac4e9a6..7460bc7e13 100644 --- a/racket/src/racket/src/longdouble/longdouble.c +++ b/racket/src/racket/src/longdouble/longdouble.c @@ -740,7 +740,7 @@ void set_long_double(long_double a, long_double b) { _imp_set_long_double(a, b); long_double long_double_from_int(int a) { return _imp_long_double_from_int(a); } long_double long_double_from_float(float a) { return _imp_long_double_from_float(a); } long_double long_double_from_double(double a) { return _imp_long_double_from_double(a); } -long_double long_double_from_intptr(uintptr_t a) { return _imp_long_double_from_intptr(a); } +long_double long_double_from_intptr(intptr_t a) { return _imp_long_double_from_intptr(a); } long_double long_double_from_uintptr(uintptr_t a) { return _imp_long_double_from_uintptr(a); } double double_from_long_double(long_double a) { return _imp_double_from_long_double(a); } diff --git a/racket/src/racket/src/longdouble/longdouble.h b/racket/src/racket/src/longdouble/longdouble.h index f9eca1c3e2..71318f6310 100644 --- a/racket/src/racket/src/longdouble/longdouble.h +++ b/racket/src/racket/src/longdouble/longdouble.h @@ -1,12 +1,10 @@ #ifndef MZ_LONGDOUBLE_H #define MZ_LONGDOUBLE_H -#if defined(_MSC_VER) -# define MZ_LONG_DOUBLE_API_IS_EXTERNAL -#endif - -#if defined(__MINGW32__) && defined(MZ_LONG_DOUBLE) -# define LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL +#ifndef MZ_LONG_DOUBLE_API_IS_EXTERNAL +# if defined(__MINGW32__) && defined(MZ_LONG_DOUBLE) +# define LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL +# endif #endif #if defined(MZ_LONG_DOUBLE_API_IS_EXTERNAL) \ diff --git a/racket/src/racket/src/mzrt.c b/racket/src/racket/src/mzrt.c index 0765aa89d6..f5a5823a8c 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -153,6 +153,9 @@ typedef struct mzrt_thread_stub_data { mz_proc_thread_start start_proc; void *data; mz_proc_thread *thread; +#ifdef WIN32 + void *res; +#endif } mzrt_thread_stub_data; void *mzrt_thread_stub(void *data){ @@ -169,6 +172,10 @@ void *mzrt_thread_stub(void *data){ res = start_proc(start_proc_data); +#ifdef WIN32 + proc_thread_self->res = res; +#endif + if (!--proc_thread_self->refcount) free(proc_thread_self); @@ -178,15 +185,18 @@ void *mzrt_thread_stub(void *data){ } #ifdef WIN32 -DWORD WINAPI mzrt_win_thread_stub(void *data) +unsigned int WINAPI mzrt_win_thread_stub(void *data) { - return (DWORD)mzrt_thread_stub(data); + (void)mzrt_thread_stub(data); + return 0; } #endif -mzrt_thread_id mz_proc_thread_self() { +mzrt_os_thread_id mz_proc_os_thread_self() { #ifdef WIN32 + /* For Windows, this result is not compatible with mz_proc_thread_id(), + so don't mix them up! */ return GetCurrentThreadId(); #else return pthread_self(); @@ -201,7 +211,14 @@ mzrt_thread_id mz_proc_thread_id(mz_proc_thread* thread) { mz_proc_thread* mzrt_proc_first_thread_init() { /* initialize mz_proc_thread struct for first thread that wasn't created with mz_proc_thread_create */ mz_proc_thread *thread = (mz_proc_thread*)malloc(sizeof(mz_proc_thread)); +#ifdef WIN32 + /* This pseudo-handle is not valid as a reference from any other thread, + but it will be distinct from all other IDs: */ + thread->threadid = GetCurrentThread(); +#else thread->threadid = mz_proc_thread_self(); +#endif + proc_thread_self = thread; thread->refcount = 1; return thread; @@ -234,7 +251,7 @@ mz_proc_thread* mz_proc_thread_create_w_stacksize(mz_proc_thread_start start_pro stub_data->thread = thread; # ifdef WIN32 thread->threadid = (HANDLE)_beginthreadex(NULL, stacksize, mzrt_win_thread_stub, stub_data, 0, NULL); - ok = (thread->threadid != -1L); + ok = (thread->threadid != (HANDLE)-1L); # else # ifdef NEED_GC_THREAD_OPS ok = !GC_pthread_create(&thread->threadid, attr, mzrt_thread_stub, stub_data); @@ -277,10 +294,8 @@ mz_proc_thread* mz_proc_thread_create(mz_proc_thread_start start_proc, void* dat void * mz_proc_thread_wait(mz_proc_thread *thread) { void *rc; #ifdef WIN32 - DWORD rcw; WaitForSingleObject(thread->threadid,INFINITE); - GetExitCodeThread(thread->threadid, &rcw); - rc = (void *)rcw; + rc = proc_thread_self->res; CloseHandle(thread->threadid); #else # ifdef NEED_GC_THREAD_OPS @@ -613,7 +628,7 @@ int mzrt_sema_destroy(mzrt_sema *s) #ifdef WIN32 -typedef struct mzrt_rwlock { +struct mzrt_rwlock { HANDLE readEvent; HANDLE writeMutex; LONG readers; diff --git a/racket/src/racket/src/mzrt.h b/racket/src/racket/src/mzrt.h index 1a1684cf5d..2eee24a79a 100644 --- a/racket/src/racket/src/mzrt.h +++ b/racket/src/racket/src/mzrt.h @@ -21,16 +21,21 @@ void mzrt_set_user_break_handler(void (*user_break_handler)(int)); #if (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)) # include -typedef DWORD mzrt_thread_id; +typedef HANDLE mzrt_thread_id; +typedef DWORD mzrt_os_thread_id; #else #include typedef pthread_t mzrt_thread_id; +typedef pthread_t mzrt_os_thread_id; #endif typedef struct mz_proc_thread { mzrt_thread_id threadid; int refcount; +#if (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)) + void *res; +#endif } mz_proc_thread; @@ -45,7 +50,7 @@ void mz_proc_thread_exit(void *rc); void mzrt_sleep(int seconds); -mzrt_thread_id mz_proc_thread_self(); +mzrt_os_thread_id mz_proc_os_thread_self(); mzrt_thread_id mz_proc_thread_id(mz_proc_thread* thread); /****************** THREAD RWLOCK ******************************************/ diff --git a/racket/src/racket/src/mzsj86g.S b/racket/src/racket/src/mzsj86g.S index 9d3da068dd..30ca6dffea 100644 --- a/racket/src/racket/src/mzsj86g.S +++ b/racket/src/racket/src/mzsj86g.S @@ -1,8 +1,65 @@ -#ifndef _WIN64 +#ifdef _WIN64 .globl _scheme_mz_setjmp _scheme_mz_setjmp: - push %EBP + + mov %RBX, (%RCX) + mov %RBP, 0x08(%RCX) + mov %RDI, 0x10(%RCX) + mov %RSI, 0x18(%RCX) + mov %RSP, 0x20(%RCX) + mov %R12, 0x28(%RCX) + mov %R13, 0x30(%RCX) + mov %R14, 0x38(%RCX) + mov %R15, 0x40(%RCX) + stmxcsr 0x48(%RCX) + movdqu %XMM6, 0x50(%RCX) + movdqu %XMM7, 0x60(%RCX) + movdqu %XMM8, 0x70(%RCX) + movdqu %XMM9, 0x80(%RCX) + movdqu %XMM10, 0x90(%RCX) + movdqu %XMM11, 0x0A0(%RCX) + movdqu %XMM12, 0x0B0(%RCX) + movdqu %XMM13, 0x0C0(%RCX) + movdqu %XMM14, 0x0D0(%RCX) + movdqu %XMM15, 0x0E0(%RCX) + mov (%RSP), %RAX + mov %RAX, 0x0F0(%RCX) + mov $0, %RAX + ret + +.globl _scheme_mz_longjmp +_scheme_mz_longjmp: + mov (%RCX), %RBX + mov 0x08(%RCX), %RBP + mov 0x10(%RCX), %RDI + mov 0x18(%RCX), %RSI + mov 0x20(%RCX), %RSP + mov 0x28(%RCX), %R12 + mov 0x30(%RCX), %R13 + mov 0x38(%RCX), %R14 + mov 0x40(%RCX), %R15 + ldmxcsr 0x48(%RCX) + movdqu 0x50(%RCX), %XMM6 + movdqu 0x60(%RCX), %XMM7 + movdqu 0x70(%RCX), %XMM8 + movdqu 0x80(%RCX), %XMM9 + movdqu 0x90(%RCX), %XMM10 + movdqu 0x0A0(%RCX), %XMM11 + movdqu 0x0B0(%RCX), %XMM12 + movdqu 0x0C0(%RCX), %XMM13 + movdqu 0x0D0(%RCX), %XMM14 + movdqu 0x0E0(%RCX), %XMM15 + mov 0x0F0(%RCX), %RAX + mov %RAX, (%RSP) + mov %RDX, %RAX + ret + +#else + +.globl _scheme_mz_setjmp +_scheme_mz_setjmp: + push %EBP mov %ESP, %EBP mov 4(%EBP), %ECX # return address mov 8(%EBP), %EAX # jmp_buf ptr @@ -34,10 +91,10 @@ _scheme_mz_longjmp: mov %ECX, 4(%EBP) pop %EBP ret - + +#endif + .section .drectve,"r" .ascii " -export:scheme_mz_setjmp" .section .drectve,"r" .ascii " -export:scheme_mz_longjmp" - -#endif diff --git a/racket/src/racket/src/network.c b/racket/src/racket/src/network.c index 565d7292d7..77b29894ad 100644 --- a/racket/src/racket/src/network.c +++ b/racket/src/racket/src/network.c @@ -597,6 +597,14 @@ static intptr_t getaddrinfo_in_thread(void *_data) return 1; } +#ifdef USE_WINSOCK_TCP +static unsigned int WINAPI win_getaddrinfo_in_thread(void *_data) + XFORM_SKIP_PROC +{ + return (unsigned int)getaddrinfo_in_thread(_data); +} +#endif + static void release_ghbn_lock(GHBN_Rec *rec) { ghbn_thread_data->ghbn_lock = 0; @@ -701,13 +709,13 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo # ifdef USE_WINSOCK_TCP { HANDLE ready_sema; - DWORD id; + unsigned int id; intptr_t th; ready_sema = CreateSemaphore(NULL, 0, 1, NULL); ghbn_thread_data->ready_sema = ready_sema; th = _beginthreadex(NULL, 5000, - (MZ_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread, + win_getaddrinfo_in_thread, ghbn_thread_data, 0, &id); WaitForSingleObject(ghbn_thread_data->ready_sema, INFINITE); CloseHandle(ghbn_thread_data->ready_sema); diff --git a/racket/src/racket/src/setjmpup.c b/racket/src/racket/src/setjmpup.c index e5e29aa4c6..8c18c5d660 100644 --- a/racket/src/racket/src/setjmpup.c +++ b/racket/src/racket/src/setjmpup.c @@ -739,3 +739,25 @@ Scheme_Setjmp_Proc scheme_get_mz_setjmp(void) return NULL; } #endif + +#if defined(USE_MZ_SETJMP_INDIRECT) && defined(__MINGW32__) +extern int _scheme_mz_setjmp(mz_pre_jmp_buf b); +extern void _scheme_mz_longjmp(mz_pre_jmp_buf b, int v); + +Scheme_Setjmp_Proc scheme_get_mz_setjmp(void) +{ + return _scheme_mz_setjmp; +} + +void scheme_mz_longjmp(mz_pre_jmp_buf b, int v) +{ + _scheme_mz_longjmp(b, v); +} + +int scheme_mz_setjmp(mz_pre_jmp_buf b) +{ + scheme_log_abort("internal error: setjmp wasn't indirect"); + abort(); + return 0; +} +#endif diff --git a/racket/src/worksp/gracket/gracket.rc b/racket/src/worksp/gracket/gracket.rc index bf333838e4..25b8eda60d 100644 --- a/racket/src/worksp/gracket/gracket.rc +++ b/racket/src/worksp/gracket/gracket.rc @@ -8,6 +8,15 @@ APPLICATION ICON DISCARDABLE "gracket.ico" +///////////////////////////////////////////////////////////////////////////// +// +// Manifest (for MinGW) +// + +#ifdef __MINGW32__ +1 RT_MANIFEST "gracket.manifest" +#endif + ///////////////////////////////////////////////////////////////////////////// // // Version diff --git a/racket/src/worksp/racket/racket.rc b/racket/src/worksp/racket/racket.rc index 9ec9edb06f..8daf0caf81 100644 --- a/racket/src/worksp/racket/racket.rc +++ b/racket/src/worksp/racket/racket.rc @@ -8,6 +8,15 @@ APPLICATION ICON DISCARDABLE "racket.ico" +///////////////////////////////////////////////////////////////////////////// +// +// Manifest (for MinGW) +// + +#ifdef __MINGW32__ +1 RT_MANIFEST "racket.manifest" +#endif + ///////////////////////////////////////////////////////////////////////////// // // Version From 828aff14763186d0fc2907895123095ed73116a3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 26 Aug 2015 10:02:02 -0600 Subject: [PATCH 105/381] unbreak non-Windows build --- racket/src/racket/src/mzrt.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/racket/src/racket/src/mzrt.c b/racket/src/racket/src/mzrt.c index f5a5823a8c..c3a5cdc7bb 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -153,9 +153,6 @@ typedef struct mzrt_thread_stub_data { mz_proc_thread_start start_proc; void *data; mz_proc_thread *thread; -#ifdef WIN32 - void *res; -#endif } mzrt_thread_stub_data; void *mzrt_thread_stub(void *data){ @@ -216,7 +213,7 @@ mz_proc_thread* mzrt_proc_first_thread_init() { but it will be distinct from all other IDs: */ thread->threadid = GetCurrentThread(); #else - thread->threadid = mz_proc_thread_self(); + thread->threadid = mz_proc_os_thread_self(); #endif proc_thread_self = thread; From 2a9022945db450fe1557fcb9335c8156b1eabfa4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 26 Aug 2015 13:13:28 -0600 Subject: [PATCH 106/381] support for building MzCOM with MinGW --- racket/src/README | 6 ++-- racket/src/mzcom/com_glue.c | 11 +++---- racket/src/mzcom/mzcom.cxx | 8 ++--- racket/src/mzcom/mzobj.cxx | 28 +++++++++++++----- racket/src/mzcom/prebuilt/MzCOM.tlb | Bin 0 -> 2300 bytes racket/src/mzcom/prebuilt/README.txt | 3 ++ racket/src/racket/Makefile.in | 42 +++++++++++++++++++++++---- racket/src/racket/delayed.inc | 4 +-- racket/src/racket/gc2/Makefile.in | 19 ++++++++++-- racket/src/racket/main.c | 30 +++---------------- racket/src/racket/src/mzrt.c | 3 +- racket/src/racket/win_tls.inc | 33 +++++++++++++++++++++ 12 files changed, 130 insertions(+), 57 deletions(-) create mode 100644 racket/src/mzcom/prebuilt/MzCOM.tlb create mode 100644 racket/src/mzcom/prebuilt/README.txt create mode 100644 racket/src/racket/win_tls.inc diff --git a/racket/src/README b/racket/src/README index 7b3d953b0e..d7920f0e77 100644 --- a/racket/src/README +++ b/racket/src/README @@ -27,9 +27,9 @@ To compile with Microsoft Visual C, read the instructions in To compile with MinGW tools, follow the Unix instructions below; do not use `--enable-shared', because DLLs will be generated automatically. -The result is a Windows-style build, but without MzCOM. If you are using -a variant of MinGW without "libdelayimp.a", get the implementation of -"delayimp.c" from MinGW-w64 and compile it to "libdelayimp.a". +The result is a Windows-style build. If you are using a variant of +MinGW without "libdelayimp.a", get the implementation of "delayimp.c" +from MinGW-w64 and compile it to "libdelayimp.a". To compile with Cygwin tools, follow the Unix instructions below. The result is a Unix-style build, not a Windows-style build (e.g., diff --git a/racket/src/mzcom/com_glue.c b/racket/src/mzcom/com_glue.c index 48a9f0e0ac..9c8fcf0866 100644 --- a/racket/src/mzcom/com_glue.c +++ b/racket/src/mzcom/com_glue.c @@ -470,8 +470,9 @@ static STDMETHODIMP Advise(IConnectionPoint *com_obj, IUnknown *obj, DWORD *cook // We need to return (to the app) some value that will clue our Unadvise() function // below how to locate this app IMzObjEvents. The simpliest thing is to just use the - // app's IMzObjEvents pointer as that returned value - *cookie = (DWORD)iExample->evts; + // app's IMzObjEvents pointer as that returned value. We may lose some bits here, + // but that's ok: + *cookie = (DWORD)(intptr_t)iExample->evts; return(hr); } @@ -496,10 +497,10 @@ static STDMETHODIMP Unadvise(IConnectionPoint *com_obj, DWORD cookie) // IMzObjEvents right now. // // Let's just make sure the cookie he passed is really the pointer we expect - if (cookie && (IMzObjEvents *)cookie == iExample->evts) + if (cookie && cookie == (DWORD)(intptr_t)iExample->evts) { // Release the app's IMzObjEvents - ((IMzObjEvents *)cookie)->lpVtbl->Release((IMzObjEvents *)cookie); + iExample->evts->lpVtbl->Release(iExample->evts); // We no longer have the app's IMzObjEvents, so clear the IMzObj // feedback member @@ -672,7 +673,7 @@ HRESULT com_register() // Initialize my IClassFactory with the pointer to its vtable MyIClassFactoryObj.lpVtbl = (IClassFactoryVtbl *)&IClassFactory_Vtbl; - return CoRegisterClassObject(&CLSID_IMzObj, &MyIClassFactoryObj, + return CoRegisterClassObject(&CLSID_IMzObj, (IUnknown*)&MyIClassFactoryObj, CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, ®_cookie); } diff --git a/racket/src/mzcom/mzcom.cxx b/racket/src/mzcom/mzcom.cxx index 263dd64f18..d87a5db74f 100644 --- a/racket/src/mzcom/mzcom.cxx +++ b/racket/src/mzcom/mzcom.cxx @@ -65,12 +65,12 @@ static bool StartMonitor() { return TRUE; } #endif -static int set_reg_string(HKEY sub, char *name, char *s) +static int set_reg_string(HKEY sub, const char *name, const char *s) { return RegSetValueExA(sub, name, 0, REG_SZ, (const BYTE *)s, strlen(s)); } -static int set_reg_sub_string(HKEY sub, char *name, char *s) +static int set_reg_sub_string(HKEY sub, const char *name, const char *s) { HKEY sub2; int nRet; @@ -86,10 +86,10 @@ static int set_reg_sub_string(HKEY sub, char *name, char *s) LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) { - while (p1 != NULL && *p1 != NULL) + while (p1 != NULL && *p1 != 0) { LPCTSTR p = p2; - while (p != NULL && *p != NULL) + while (p != NULL && *p != 0) { if (*p1 == *p) return CharNext(p1); diff --git a/racket/src/mzcom/mzobj.cxx b/racket/src/mzcom/mzobj.cxx index e5df4c4487..698988656f 100644 --- a/racket/src/mzcom/mzobj.cxx +++ b/racket/src/mzcom/mzobj.cxx @@ -35,7 +35,7 @@ END_XFORM_SKIP; START_XFORM_SKIP; #endif -static void ErrorBox(char *s) { +static void ErrorBox(const char *s) { ::MessageBox(NULL,s,"MzCOM",MB_OK); } @@ -112,12 +112,12 @@ static Scheme_Object *eval_string_or_get_exn_message(char *s) { return exn; } -OLECHAR *wideStringFromSchemeObj(Scheme_Object *obj,char *fmt,int fmtlen) { +OLECHAR *wideStringFromSchemeObj(Scheme_Object *obj,const char *fmt,int fmtlen) { char *s; OLECHAR *wideString; int len; - s = scheme_format_utf8(fmt,fmtlen,1,&obj,NULL); + s = scheme_format_utf8((char *)fmt,fmtlen,1,&obj,NULL); len = strlen(s); wideString = (OLECHAR *)scheme_malloc((len + 1) * sizeof(OLECHAR)); MultiByteToWideChar(CP_ACP,(DWORD)0,s,len,wideString,len + 1); @@ -133,7 +133,7 @@ void exitHandler(int) { void setupSchemeEnv(Scheme_Env *in_env) { - char *wrapper; + const char *wrapper; char exeBuff[260]; HMODULE mod; static BOOL registered; @@ -308,12 +308,10 @@ static int record_at_exit(Scheme_At_Exit_Callback_Proc p) XFORM_SKIP_PROC return 0; } -static __declspec(thread) void *tls_space; +#include "../racket/win_tls.inc" static unsigned WINAPI evalLoop(void *args) XFORM_SKIP_PROC { -#ifndef _WIN64 - scheme_register_tls_space(&tls_space, 0); -#endif + register_win_tls(); scheme_set_atexit(record_at_exit); return scheme_main_setup(1, do_evalLoop, 0, (char **)args); @@ -563,6 +561,20 @@ HRESULT mzobj_eval(void *o, BSTR s, BSTR *r) return ((CMzObj *)o)->Eval(s, r); } +#ifdef __MINGW32__ + +void * operator new(size_t n) +{ + return malloc(n); +} + +void operator delete(void * p) +{ + free(p); +} + +#endif + #ifdef MZ_PRECISE_GC END_XFORM_SKIP; #endif diff --git a/racket/src/mzcom/prebuilt/MzCOM.tlb b/racket/src/mzcom/prebuilt/MzCOM.tlb new file mode 100644 index 0000000000000000000000000000000000000000..25ee5c77b5faba1ddda422b598a94790e3559a9b GIT binary patch literal 2300 zcmcImO-NKx6h1SJHZ?|>(H|~uP>Uq&Iam%+VyThfU_ZvI5Skh1mBu(DZ=RZEP4*fk6)<9}qP_y39 zXJJ={J`oLaYyZ#CUmEs$_6$th>#IfH8ur*?k!yy21A5%h83%PPehT(pL;nnYqoG&& zSLz!#pnnz!NzV@>_=z$^R*0+$Eu5t$=8d3J-K&Xj+7pq!d1`1MQ%*s_cq9{o`$9>< z8nhXyd@J$hJ<)k<=>7PP;bR)ItyaVf^&_FAV6KSl_iJzlQNch%oHo*BL$9<29`ipl zaGnOA2Adw-Gj;BjGc|2`Z2`abG0|9Z>F&WCU_W+Q>chF?UFkDD zxl^5^PSGplyl7iOt}Hv$Ki~{GovvGQ=gv_=o~XQ2?so@=y}?q^*5|k?_2z<~2|4r` zu1-BV8>Ih^#bj5pb2MAfy;n&?bg(!);u&YPT8@4yjd(t&b5+Ut&AW3zjr>(o*Lu(? zJH%E?`V4lbni?(DJ3j0v?9*K z?_`Is1?RsTYksG%#1K3Rey!R;qf zfQ_+ye>L63VkuZ5la6bXX8bo{=71(36tZahKHsjhid=%7-b8rOT?9{qc?Xf$(-H7D DT{!?J literal 0 HcmV?d00001 diff --git a/racket/src/mzcom/prebuilt/README.txt b/racket/src/mzcom/prebuilt/README.txt new file mode 100644 index 0000000000..46996bf6bc --- /dev/null +++ b/racket/src/mzcom/prebuilt/README.txt @@ -0,0 +1,3 @@ +Scine MinGW doesn't currently include `widl`, since installing it with +Wine is a pain, and since the output is not platform-specific, we +include "MzCOM.tlb" as pre-built from "mzcom.idl". diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index d5c7edcca6..7c27d9b68a 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -89,13 +89,15 @@ cgc: $(MAKE) common $(MAKE) dynlib $(MAKE) mzlibrary - $(MAKE) racket@CGC@ + $(MAKE) racket@CGC@ + $(MAKE) mzcom@CGC@ 3m: $(MAKE) @CGC_IF_NEEDED_FOR_MMM@ cd gc2; $(MAKE) all cd dynsrc; $(MAKE) dynlib3m cd gc2; $(MAKE) ../racket@MMM@ + cd gc2; $(MAKE) ../mzcom@MMM@ both: $(MAKE) cgc @@ -173,6 +175,9 @@ sproc.@LTO@: @GCDIR@/sproc.@LTO@ racket@CGC@@NOT_OSX@@NOT_MINGW@: libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@ $(SPECIALIZINGOBJECTS) @MZLINKER@ -o racket@CGC@ main.@LTO@ $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LDFLAGS@ @LIBS@ +mzcom@CGC@@NOT_MINGW@: + $(NOOP) + # Mac OS ---------------------------------------- MZFW = Racket.framework/Versions/$(FWVERSION)/Racket @@ -209,15 +214,23 @@ libmzgc.dll.a: lib/libmzgcxxxxxxx.dll rres.o : $(srcdir)/../worksp/racket/racket.rc @WINDRES@ -i $(srcdir)/../worksp/racket/racket.rc -o rres.o -racket@CGC@@MINGW@: libracket.dll.a libmzgc.dll.a main.@LTO@ $(SPECIALIZINGOBJECTS) rres.o - @MZLINKER@ -o racket@CGC@ main.@LTO@ rres.o $(SPECIALIZINGOBJECTS) libracket.dll.a libmzgc.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgcc +MW_RACKET_LIBS = libracket.dll.a libmzgc.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgcc -mingw-other@MINGW@: mzsj86g.o rres.o +racket@CGC@@MINGW@: libracket.dll.a libmzgc.dll.a main.@LTO@ $(SPECIALIZINGOBJECTS) rres.o + @MZLINKER@ -o racket@CGC@ main.@LTO@ rres.o $(SPECIALIZINGOBJECTS) $(MW_RACKET_LIBS) + +mingw-other@MINGW@: mzsj86g.o rres.o comres.o com_glue.@LTO@ $(NOOP) mingw-other@NOT_MINGW@: $(NOOP) +mzcom@CGC@@MINGW@: libracket.dll.a libmzgc.dll.a mzcom.@LTO@ mzobj.@LTO@ com_glue.@LTO@ $(SPECIALIZINGOBJECTS) comres.o + @MZLINKER@ -o mzcom@CGC@ mzcom.@LTO@ mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS) + +comres.o : $(srcdir)/../worksp/mzcom/mzcom.rc $(srcdir)/../mzcom/prebuilt/MzCOM.tlb + @WINDRES@ -I $(srcdir)/../mzcom -I $(srcdir)/../mzcom/prebuilt -i $(srcdir)/../worksp/mzcom/mzcom.rc -o comres.o + # OSKit ---------------------------------------- racket.multiboot : libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@ @@ -238,7 +251,7 @@ DEF_C_DIRS = $(DEF_COLLECTS_DIR) $(DEF_CONFIG_DIR) MAIN_HEADER_DEPS = $(srcdir)/include/scheme.h $(srcdir)/include/schthread.h $(srcdir)/sconfig.h \ $(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/parse_cmdl.inc \ - $(srcdir)/oskglue.inc + $(srcdir)/oskglue.inc $(srcdir)/delayed.inc $(srcdir)/parse_cmdl.inc main.@LTO@: $(srcdir)/main.c $(MAIN_HEADER_DEPS) $(CC) -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ $(DEF_C_DIRS) -c $(srcdir)/main.c -o main.@LTO@ @@ -257,6 +270,17 @@ mzstart.exe: $(srcdir)/dynsrc/start.c starter: mzstart.exe +MZCOM_DEPS = $(MAIN_HEADER_DEPS) $(srcdir)/../mzcom/com_glue.h $(srcdir)/../mzcom/resource.h + +mzcom.@LTO@: $(srcdir)/../mzcom/mzcom.cxx $(MZCOM_DEPS) + $(CC) -fno-exceptions -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ $(DEF_C_DIRS) -c $(srcdir)/../mzcom/mzcom.cxx -o mzcom.@LTO@ + +mzobj.@LTO@: $(srcdir)/../mzcom/mzobj.cxx $(MZCOM_DEPS) + $(CC) -fno-exceptions -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ -c $(srcdir)/../mzcom/mzobj.cxx -o mzobj.@LTO@ + +com_glue.@LTO@: $(srcdir)/../mzcom/com_glue.c $(MZCOM_DEPS) + $(CC) -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ -c $(srcdir)/../mzcom/com_glue.c -o com_glue.@LTO@ + exn: $(MAKE) $(srcdir)/src/schexn.h $(MAKE) $(collectsdir)/racket/private/kernstruct.rkt @@ -403,14 +427,18 @@ mingw-install: cd ..; cp racket/mrstarter@EXE_SUFFIX@ "$(DESTDIR)$(libpltdir)/MrStart@EXE_SUFFIX@" cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/MzStart@EXE_SUFFIX@" cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/MrStart@EXE_SUFFIX@" + cp "$(srcdir)/../mzcom/prebuilt/MzCOM.tlb" MzCOM.tlb + cd ..; cp racket/MzCOM.tlb "$(DESTDIR)$(libpltdir)/MzCOM.tlb" mingw-install-cgc: cd ..; $(ICP) racket/lib/libmzgcxxxxxxx.dll "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" cd ..; $(ICP) racket/lib/libracketxxxxxxx.dll "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll" cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" + cd ..; $(ICP) racket/mzcom@CGC@ "$(DESTDIR)$(libdir)/MzCOM@CGC_INSTALLED@@EXE_SUFFIX@" cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll" cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/MzCOM@CGC_INSTALLED@@EXE_SUFFIX@" @RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ mingw-install-cgc-final: @@ -418,9 +446,11 @@ mingw-install-cgc-final: mingw-install-3m: cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" + cd ..; $(ICP) racket/mzcom@MMM@ "$(DESTDIR)$(libdir)/MzCOM@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(ICP) racket/lib/libracket3mxxxxxxx.dll "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll" - cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/MzCOM@MMM_INSTALLED@@EXE_SUFFIX@" @RUN_RACKET_MMM@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ mingw-install-3m-final: diff --git a/racket/src/racket/delayed.inc b/racket/src/racket/delayed.inc index 96a5b1ffe1..551e4d4f93 100644 --- a/racket/src/racket/delayed.inc +++ b/racket/src/racket/delayed.inc @@ -21,10 +21,10 @@ static int _dlldir_offset = 14; /* Skip permanent tag */ START_XFORM_SKIP; # endif -static void load_delayed_dll(HINSTANCE me, char *lib) +static void load_delayed_dll(HINSTANCE me, const char *lib) { /* Don't use the C library here! */ - wchar_t *dlldir = _dlldir + _dlldir_offset; + const wchar_t *dlldir = _dlldir + _dlldir_offset; if (dlldir[0] != '<') { if ((dlldir[0] == '\\') diff --git a/racket/src/racket/gc2/Makefile.in b/racket/src/racket/gc2/Makefile.in index e2051fd08a..2e33b27767 100644 --- a/racket/src/racket/gc2/Makefile.in +++ b/racket/src/racket/gc2/Makefile.in @@ -313,6 +313,9 @@ $(XSRCDIR)/foreign.c: $(XFORMDEP) $(XSRCDIR)/main.c: $(XFORMDEP) $(XFORM_NOPRECOMP) $(XSRCDIR)/main.c $(DEF_C_DIRS) $(srcdir)/../main.c +$(XSRCDIR)/mzobj.cxx: $(XFORMDEP) + $(XFORM_NOPRECOMP) $(XSRCDIR)/mzobj.cxx $(DEF_C_DIRS) $(srcdir)/../../mzcom/mzobj.cxx + salloc.@LTO@: $(XSRCDIR)/salloc.c $(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/salloc.c -o salloc.@LTO@ bignum.@LTO@: $(XSRCDIR)/bignum.c @@ -428,6 +431,11 @@ foreign.@LTO@: $(XSRCDIR)/foreign.c main.@LTO@: $(XSRCDIR)/main.c $(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/main.c -o main.@LTO@ +mzcom.@LTO@: $(srcdir)/../../mzcom/mzcom.cxx + $(CC) -DMZCOM_3M $(ALL_CFLAGS) -fno-exceptions -c $(srcdir)/../../mzcom/mzcom.cxx -o mzcom.@LTO@ +mzobj.@LTO@: $(XSRCDIR)/mzobj.cxx + $(CC) $(ALL_CFLAGS) -fno-exceptions -c $(XSRCDIR)/mzobj.cxx -o mzobj.@LTO@ + gc2.@LTO@: \ $(srcdir)/alloc_cache.c \ $(srcdir)/block_cache.c \ @@ -523,9 +531,16 @@ $(MZFWMMM): ../libracket3m.@LIBSFX@ libracket3m.dll.a: ../lib/libracket3mxxxxxxx.dll @DLLTOOL@ --def libracket3m.def -D libracket3mxxxxxxx.dll --output-delaylib libracket3m.dll.a -../racket@MMM@@MINGW@: libracket3m.dll.a main.@LTO@ ../rres.o $(SPECIALIZINGOBJECTS) - cd ..; @MZLINKER@ -o racket@MMM@ gc2/main.@LTO@ rres.o $(SPECIALIZINGOBJECTS) gc2/libracket3m.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgcc +MW_RACKET_LIBS = gc2/libracket3m.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgcc +../racket@MMM@@MINGW@: libracket3m.dll.a main.@LTO@ ../rres.o $(SPECIALIZINGOBJECTS) + cd ..; @MZLINKER@ -o racket@MMM@ gc2/main.@LTO@ rres.o $(SPECIALIZINGOBJECTS) $(MW_RACKET_LIBS) + +../mzcom@MMM@@NOT_MINGW@: + $(NOOP) + +../mzcom@MMM@@MINGW@: libracket3m.dll.a mzcom.@LTO@ mzobj.@LTO@ ../com_glue.@LTO@ $(SPECIALIZINGOBJECTS) ../comres.o + cd ..; @MZLINKER@ -o mzcom@MMM@ gc2/mzcom.@LTO@ gc2/mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS) clean: /bin/rm -f ../racket@MMM@ *.@LTO@ $(XSRCDIR)/* diff --git a/racket/src/racket/main.c b/racket/src/racket/main.c index 47dcbf98c2..690c5d2068 100644 --- a/racket/src/racket/main.c +++ b/racket/src/racket/main.c @@ -292,13 +292,8 @@ START_XFORM_SKIP; # include "parse_cmdl.inc" #endif -#ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS -extern intptr_t _tls_index; -# ifdef __MINGW32__ -static __thread void *tls_space; -# else -static __declspec(thread) void *tls_space; -# endif +#ifdef DOS_FILE_SYSTEM +# include "win_tls.inc" #endif #ifdef DOS_FILE_SYSTEM @@ -314,25 +309,8 @@ void load_delayed() load_delayed_dll(NULL, "libracket" DLL_3M_SUFFIX "xxxxxxx.dll"); # endif record_dll_path(); -# ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS -# ifdef __MINGW32__ - { - /* gcc declares space for the thread-local variable in a way that - the OS can set up, but its doesn't actually map variables - through the OS-supplied mechanism. Just assume that the first - thread-local variable is ours. */ - void **base; -# ifdef _WIN64 - asm("mov %%gs:(0x58), %0;" :"=r"(base)); -# else - asm("mov %%fs:(0x2C), %0;" :"=r"(base)); -# endif - scheme_register_tls_space(*base, _tls_index); - } -# else - scheme_register_tls_space(&tls_space, _tls_index); -# endif -# endif + + register_win_tls(); } #endif diff --git a/racket/src/racket/src/mzrt.c b/racket/src/racket/src/mzrt.c index c3a5cdc7bb..7cd89e26b6 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -328,7 +328,8 @@ int mz_proc_thread_detach(mz_proc_thread *thread) { void mz_proc_thread_exit(void *rc) { #ifdef WIN32 - _endthreadex((unsigned)rc); + proc_thread_self->res = rc; + _endthreadex(0); #else # ifndef MZ_PRECISE_GC pthread_exit(rc); diff --git a/racket/src/racket/win_tls.inc b/racket/src/racket/win_tls.inc new file mode 100644 index 0000000000..fdfc3376bb --- /dev/null +++ b/racket/src/racket/win_tls.inc @@ -0,0 +1,33 @@ +#ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS +extern intptr_t _tls_index; +# ifdef __MINGW32__ +static __thread void *tls_space; +# else +static __declspec(thread) void *tls_space; +# endif +#endif + +# ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS +static void register_win_tls() +{ +# ifdef __MINGW32__ + { + /* gcc declares space for the thread-local variable in a way that + the OS can set up, but its doesn't actually map variables + through the OS-supplied mechanism. Just assume that the first + thread-local variable is ours. */ + void **base; +# ifdef _WIN64 + asm("mov %%gs:(0x58), %0;" :"=r"(base)); +# else + asm("mov %%fs:(0x2C), %0;" :"=r"(base)); +# endif + scheme_register_tls_space(*base, _tls_index); + } +# else + scheme_register_tls_space(&tls_space, _tls_index); +# endif +} +# else +static void register_win_tls() {} +# endif From a3972487fb52bf78a02ab7ab8010b71fe236f60a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 27 Aug 2015 07:10:08 -0600 Subject: [PATCH 107/381] unbreak Linux build --- racket/src/racket/gc2/sighand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/sighand.c b/racket/src/racket/gc2/sighand.c index 9f5ac3cbcf..f92e7063ab 100644 --- a/racket/src/racket/gc2/sighand.c +++ b/racket/src/racket/gc2/sighand.c @@ -84,7 +84,7 @@ void fault_handler(int sn, siginfo_t *si, void *ctx) /* running w/ places in GDB */ printf("SIGSEGV SI_USER SI_ERRNO %i fault on addr %p\n", si->si_errno, p); #ifdef MZ_USE_PLACES - printf("pid %i uid %i thread %lx\n", si->si_pid, si->si_uid, mz_proc_thread_self()); + printf("pid %i uid %i thread %lx\n", si->si_pid, si->si_uid, mz_proc_os_thread_self()); #else printf("pid %i uid %i\n", si->si_pid, si->si_uid); #endif From d4fb5ecec5cb5d659031f2d300bbb1d6f1869996 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 26 Aug 2015 16:18:45 -0600 Subject: [PATCH 108/381] fix "GRacket.exe" capilization for MinGW build --- racket/src/gracket/Makefile.in | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/racket/src/gracket/Makefile.in b/racket/src/gracket/Makefile.in index c5330870ec..2e6ce4e061 100644 --- a/racket/src/gracket/Makefile.in +++ b/racket/src/gracket/Makefile.in @@ -202,11 +202,14 @@ install-no-lib-cgc-wx_xt: install-lib-cgc-wx_xt: $(NOOP) +GRACKET_NAME@NOT_MINGW@ = gracket +GRACKET_NAME@MINGW@ = GRacket + install-wx_xt-cgc: $(MAKE) @MRLIBINSTALL@-cgc-wx_xt - cd ..; $(ICP) gracket/gracket@CGC@ "$(DESTDIR)$(libpltdir)/gracket@CGC_INSTALLED@@EXE_SUFFIX@" - cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/gracket@CGC_INSTALLED@@EXE_SUFFIX@" - @RUN_RACKET_CGC@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/gracket@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ + cd ..; $(ICP) gracket/gracket@CGC@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@" + cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@" + @RUN_RACKET_CGC@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ install-wx_xt-cgc-final: $(NOOP) @@ -219,9 +222,9 @@ install-lib-3m-wx_xt: install-wx_xt-3m: $(MAKE) @MRLIBINSTALL@-3m-wx_xt - cd ..; $(ICP) gracket/gracket@MMM@ "$(DESTDIR)$(libpltdir)/gracket@MMM_INSTALLED@@EXE_SUFFIX@" - cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/gracket@MMM_INSTALLED@@EXE_SUFFIX@" - @RUN_RACKET_MMM@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/gracket@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ + cd ..; $(ICP) gracket/gracket@MMM@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@" + cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@" + @RUN_RACKET_MMM@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ install-wx_xt-3m-final: $(NOOP) From a98947e81ec720c4ccc37e4c6eb187e4bbb34c53 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 27 Aug 2015 09:54:53 -0600 Subject: [PATCH 109/381] fix MSVC MzCOM build --- racket/src/racket/win_tls.inc | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/racket/src/racket/win_tls.inc b/racket/src/racket/win_tls.inc index fdfc3376bb..deace2adcb 100644 --- a/racket/src/racket/win_tls.inc +++ b/racket/src/racket/win_tls.inc @@ -1,33 +1,39 @@ #ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS + +# ifndef NO_TLS_INDEX_FOR_WIN_TLS extern intptr_t _tls_index; +# define REGISTER_TLS_INDEX_ARG _tls_index +# else +# define REGISTER_TLS_INDEX_ARG 0 +# endif + # ifdef __MINGW32__ static __thread void *tls_space; # else static __declspec(thread) void *tls_space; # endif -#endif -# ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS static void register_win_tls() { -# ifdef __MINGW32__ +# ifdef __MINGW32__ { /* gcc declares space for the thread-local variable in a way that the OS can set up, but its doesn't actually map variables through the OS-supplied mechanism. Just assume that the first thread-local variable is ours. */ void **base; -# ifdef _WIN64 +# ifdef _WIN64 asm("mov %%gs:(0x58), %0;" :"=r"(base)); -# else - asm("mov %%fs:(0x2C), %0;" :"=r"(base)); -# endif - scheme_register_tls_space(*base, _tls_index); - } -# else - scheme_register_tls_space(&tls_space, _tls_index); -# endif -} # else -static void register_win_tls() {} + asm("mov %%fs:(0x2C), %0;" :"=r"(base)); # endif + scheme_register_tls_space(*base, REGISTER_TLS_INDEX_ARG); + } +# else + scheme_register_tls_space(&tls_space, REGISTER_TLS_INDEX_ARG); +# endif +} + +#else +static void register_win_tls() {} +#endif From 29784bda8e4d5a2fa464d44a3c624bc0cb879f06 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 26 Aug 2015 18:00:43 -0600 Subject: [PATCH 110/381] add `cross-system-type` and `cross-system-library-subpath` Adjust installation tools to support cross-installation (i.e., installation for a platform other than the current one) as triggered by "system.rktd" in "lib" having different information than the running Racket executable. --- pkgs/base/info.rkt | 2 +- pkgs/racket-doc/pkg/scribblings/lib.scrbl | 2 +- pkgs/racket-doc/scribblings/raco/common.rkt | 3 + pkgs/racket-doc/scribblings/raco/setup.scrbl | 78 +++- .../scribblings/reference/runtime.scrbl | 11 +- racket/collects/compiler/distribute.rkt | 19 +- racket/collects/compiler/embed.rkt | 45 +- racket/collects/launcher/launcher.rkt | 51 ++- racket/collects/pkg/lib.rkt | 2 +- racket/collects/pkg/private/addl-installs.rkt | 1 + racket/collects/pkg/private/dep.rkt | 2 +- racket/collects/pkg/strip.rkt | 5 +- racket/collects/setup/cross-system.rkt | 77 ++++ racket/collects/setup/dirs.rkt | 432 +++--------------- racket/collects/setup/matching-platform.rkt | 18 +- racket/collects/setup/parallel-do.rkt | 6 +- racket/collects/setup/private/dirs.rkt | 314 +++++++++++++ racket/collects/setup/setup-core.rkt | 16 +- racket/collects/setup/variant.rkt | 32 +- racket/src/racket/Makefile.in | 18 +- racket/src/racket/gc2/Makefile.in | 2 +- racket/src/racket/mksystem.rkt | 75 +++ racket/src/racket/src/Makefile.in | 2 +- racket/src/racket/src/schvers.h | 4 +- racket/src/racket/src/string.c | 36 +- racket/src/racket/src/systype.c | 16 + racket/src/racket/src/systype.inc | 37 ++ racket/src/worksp/gc2/make.rkt | 3 + racket/src/worksp/racket/racket.vcproj | 16 +- 29 files changed, 830 insertions(+), 495 deletions(-) create mode 100644 racket/collects/setup/cross-system.rkt create mode 100644 racket/collects/setup/private/dirs.rkt create mode 100644 racket/src/racket/mksystem.rkt create mode 100644 racket/src/racket/src/systype.c create mode 100644 racket/src/racket/src/systype.inc diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 339b282d45..cc51c43723 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.10") +(define version "6.2.900.11") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/pkg/scribblings/lib.scrbl b/pkgs/racket-doc/pkg/scribblings/lib.scrbl index c5f74772e7..13cf6f6444 100644 --- a/pkgs/racket-doc/pkg/scribblings/lib.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/lib.scrbl @@ -678,7 +678,7 @@ represented by @racket[dir] and named @racket[pkg-name].} [pkg-name string] [#:namespace namespace namespace? (make-base-namespace)] [#:system-type sys-type (or/c #f symbol?) (system-type)] - [#:system-library-subpath sys-lib-subpath (or/c #f path?) + [#:system-library-subpath sys-lib-subpath (or/c #f path-for-some-system?) (system-library-subpath #f)]) (listof (cons/c symbol? string?))]{ diff --git a/pkgs/racket-doc/scribblings/raco/common.rkt b/pkgs/racket-doc/scribblings/raco/common.rkt index 983db069ba..be564f6ce5 100644 --- a/pkgs/racket-doc/scribblings/raco/common.rkt +++ b/pkgs/racket-doc/scribblings/raco/common.rkt @@ -7,5 +7,8 @@ (define inside-doc '(lib "scribblings/inside/inside.scrbl")) +(define guide-doc + '(lib "scribblings/guide/guide.scrbl")) + (define reference-doc '(lib "scribblings/reference/reference.scrbl")) diff --git a/pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-doc/scribblings/raco/setup.scrbl index e2a3f2b833..58d6b50d9f 100644 --- a/pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -14,6 +14,7 @@ setup/collection-name setup/collection-search setup/matching-platform + setup/cross-system setup/path-to-relative setup/xref scribble/xref ;; info -- no bindings from this are used @@ -1782,9 +1783,14 @@ Returns @racket[#t] if @racket[v] is a symbol, string, or regexp value (in the sense of @racket[regexp?]), @racket[#f] otherwise.} @defproc[(matching-platform? [spec platform-spec?] - [#:system-type sys-type (or/c #f symbol?) (system-type)] - [#:system-library-subpath sys-lib-subpath (or/c #f path?) - (system-library-subpath #f)]) + [#:cross? cross? any/c #f] + [#:system-type sys-type (or/c #f symbol?) (if cross? + (cross-system-type) + (system-type))] + [#:system-library-subpath sys-lib-subpath (or/c #f path-for-some-system?) + (if cross? + (cross-system-library-subpath #f) + (system-library-subpath #f))]) boolean?]{ Reports whether @racket[spec] matches @racket[sys-type] or @@ -1800,8 +1806,74 @@ If @racket[spec] is a string, then the result is @racket[#t] if If @racket[spec] is a regexp value, then the result is @racket[#t] if the regexp matches @racket[(path->string sys-lib-subpath)], +@racket[#f] otherwise. + +@history[#:changed "6.2.900.11" @elem{Added @racket[#:cross?] argument and + changed the contract on @racket[sys-lib-subpath] + to accept @racket[path-for-some-system?] + instead of just @racket[path?].}]} + +@; ------------------------------------------------------------------------ + +@section[#:tag "cross-system"]{API for Cross-Platform Configuration} + +@defmodule[setup/cross-system]{The @racketmodname[setup/cross-system] +library provides functions for querying the system properties of a +destination platform, which can be different than the current platform +in cross-installation modes.} + +A Racket installation includes a @filepath{system.rktd} file in the +directory reported by @racket[(find-lib-dir)]. When the information in that file +does not match the running Racket's information, then the +@racketmodname[setup/cross-system] module infers that Racket is being +run in cross-installation mode. + +For example, if an in-place Racket installation for a different +platform resides at @nonterm{cross-dir}, then + +@commandline{racket -G @nonterm{cross-dir}/etc -X @nonterm{cross-dir}/collects -l- raco pkg} + +runs @exec{raco pkg} using the current platform's @exec{racket} +executable, but using the collections and other configuration +information of @nonterm{cross-dir}, as well as modifying the packages +of @nonterm{cross-dir}. That can work as long as no platform-specific +libraries need to run to perform the requested @exec{raco pkg} action +(e.g., when installing built packages). + + +@history[#:added "6.2.900.11"] + +@defproc[(cross-system-type [mode (or/c 'os 'word 'gc 'link 'machine + 'so-suffix 'so-mode 'fs-change) + 'os]) + (or/c symbol? string? bytes? exact-positive-integer? vector?)]{ + +Like @racket[system-type], but for the target platform instead of the +current platform in cross-installation mode. When not in +cross-installation mode, the results are the same as for +@racket[system-type].} + + +@defproc[(cross-system-library-subpath [mode (or/c 'cgc '3m #f) + (system-type 'gc)]) + path-for-some-system?]{ + +Like @racket[system-library-subpath], but for the target platform +instead of the current platform in cross-installation mode. When not +in cross-installation mode, the results are the same as for +@racket[system-library-subpath]. + +In cross-installation mode, the target platform may have a different +path convention than the current platform, so the result is +@racket[path-for-some-system?] instead of @racket[path?].} + + +@defproc[(cross-installation?) boolean?]{ + +Returns @racket[#t] if cross-installation mode has been detected, @racket[#f] otherwise.} + @; ------------------------------------------------------------------------ @section[#:tag "xref"]{API for Cross-References for Installed Manuals} diff --git a/pkgs/racket-doc/scribblings/reference/runtime.scrbl b/pkgs/racket-doc/scribblings/reference/runtime.scrbl index 80f441f91d..cfce564784 100644 --- a/pkgs/racket-doc/scribblings/reference/runtime.scrbl +++ b/pkgs/racket-doc/scribblings/reference/runtime.scrbl @@ -1,5 +1,6 @@ #lang scribble/doc -@(require "mz.rkt") +@(require "mz.rkt" + (for-label setup/cross-system)) @title[#:tag "runtime"]{Environment and Runtime Information} @@ -9,7 +10,8 @@ (or/c symbol? string? bytes? exact-positive-integer? vector?)]{ Returns information about the operating system, build mode, or machine -for a running Racket. +for a running Racket. (Installation tools should use @racket[cross-system-type], +instead, to support cross-installation.) In @indexed-racket['os] mode, the possible symbol results are: @@ -117,7 +119,10 @@ The optional @racket[mode] argument specifies the relevant garbage-collection variant, which one of the possible results of @racket[(system-type 'gc)]: @racket['cgc] or @racket['3m]. It can also be @racket[#f], in which case the result is independent of the -garbage-collection variant.} +garbage-collection variant. + +Installation tools should use @racket[cross-system-library-subpath], +instead, to support cross-installation.} @defproc[(version) (and/c string? immutable?)]{ diff --git a/racket/collects/compiler/distribute.rkt b/racket/collects/compiler/distribute.rkt index bfad737437..ca6d6291af 100644 --- a/racket/collects/compiler/distribute.rkt +++ b/racket/collects/compiler/distribute.rkt @@ -4,6 +4,7 @@ setup/dirs racket/list setup/variant + setup/cross-system pkg/path setup/main-collects dynext/filename-version @@ -22,7 +23,7 @@ [_ (unless (directory-exists? dest-dir) (make-directory dest-dir))] [sub-dirs (map (lambda (b type) - (case (system-type) + (case (cross-system-type) [(windows) #f] [(unix) "bin"] [(macosx) (if (memq type '(gracketcgc gracket3m)) @@ -41,7 +42,7 @@ (let-values ([(base name dir?) (split-path b)]) (let ([dest (build-path dest-dir name)]) (if (and (memq type '(gracketcgc gracket3m)) - (eq? 'macosx (system-type))) + (eq? 'macosx (cross-system-type))) (begin (copy-app b dest) (app-to-file dest)) @@ -51,7 +52,7 @@ orig-binaries sub-dirs types)] - [single-mac-app? (and (eq? 'macosx (system-type)) + [single-mac-app? (and (eq? 'macosx (cross-system-type)) (= 1 (length types)) (memq (car types) '(gracketcgc gracket3m)))]) ;; Create directories for libs, collects, and extensions: @@ -111,7 +112,7 @@ (cond [sub-dir (build-path 'up relative-dir)] - [(and (eq? 'macosx (system-type)) + [(and (eq? 'macosx (cross-system-type)) (memq type '(gracketcgc gracket3m)) (not single-mac-app?)) (build-path 'up 'up 'up relative-dir)] @@ -139,7 +140,7 @@ (void)))))) (define (install-libs lib-dir types) - (case (system-type) + (case (cross-system-type) [(windows) (let ([copy-dll (lambda (name) (copy-file* (search-dll (find-dll-dir) name) @@ -275,7 +276,7 @@ (build-path lib-dir (car files))))) (define (patch-binaries binaries types) - (case (system-type) + (case (cross-system-type) [(windows) (for-each (lambda (b) (update-dll-dir b "lib")) @@ -565,7 +566,7 @@ ;; Utilities (define (shared-libraries?) - (eq? 'shared (system-type 'link))) + (eq? 'shared (cross-system-type 'link))) (define (to-path s) (if (string? s) @@ -580,7 +581,7 @@ (let ([m (regexp-match #rx#"bINARy tYPe:(e?)(.)(.)(.)" (current-input-port))]) (if m (begin - (when (eq? 'unix (system-type)) + (when (eq? 'unix (cross-system-type)) (unless (equal? (cadr m) #"e") (error 'assemble-distribution "file is an original PLT executable, not a stub binary: ~e" @@ -635,7 +636,7 @@ (copy-directory/files src dest)) (define (app-to-file b) - (if (and (eq? 'macosx (system-type)) + (if (and (eq? 'macosx (cross-system-type)) (regexp-match #rx#"[.][aA][pP][pP]$" (path->bytes (if (string? b) (string->path b) diff --git a/racket/collects/compiler/embed.rkt b/racket/collects/compiler/embed.rkt index 5bf8add8f4..105b4966eb 100644 --- a/racket/collects/compiler/embed.rkt +++ b/racket/collects/compiler/embed.rkt @@ -12,6 +12,7 @@ setup/variant file/ico racket/private/so-search + setup/cross-system "private/winsubsys.rkt" "private/macfw.rkt" "private/mach-o.rkt" @@ -84,10 +85,10 @@ #f) (define (embedding-executable-is-actually-directory? mred?) - (and mred? (eq? 'macosx (system-type)))) + (and mred? (eq? 'macosx (cross-system-type)))) (define (embedding-executable-put-file-extension+style+filters mred?) - (case (system-type) + (case (cross-system-type) [(windows) (values "exe" null '(("Executable" "*.exe")))] [(macosx) (if mred? (values "app" '(enter-packages) '(("App" "*.app"))) @@ -102,7 +103,7 @@ (if (regexp-match re (path->bytes path)) path (path-replace-suffix path sfx)))]) - (case (system-type) + (case (cross-system-type) [(windows) (fixup #rx#"[.][eE][xX][eE]$" #".exe")] [(macosx) (if mred? (fixup #rx#"[.][aA][pP][pP]$" #".app") @@ -118,7 +119,7 @@ dest)) (define exe-suffix? - (delay (equal? #"i386-cygwin" (path->bytes (system-library-subpath))))) + (delay (equal? #"i386-cygwin" (path->bytes (cross-system-library-subpath))))) ;; Find the magic point in the binary: (define (find-cmdline what rx) @@ -1343,7 +1344,7 @@ cmdline [aux null] [launcher? #f] - [variant (system-type 'gc)] + [variant (cross-system-type 'gc)] [collects-path #f]) (create-embedding-executable dest #:mred? mred? @@ -1374,7 +1375,7 @@ #:cmdline [cmdline null] #:aux [aux null] #:launcher? [launcher? #f] - #:variant [variant (system-type 'gc)] + #:variant [variant (cross-system-type 'gc)] #:collects-path [collects-path #f] #:collects-dest [collects-dest #f] #:on-extension [on-extension #f] @@ -1389,18 +1390,18 @@ (let ([m (assq 'forget-exe? aux)]) (or (not m) (not (cdr m)))))) - (define unix-starter? (and (eq? (system-type) 'unix) + (define unix-starter? (and (eq? (cross-system-type) 'unix) (let ([m (assq 'original-exe? aux)]) (or (not m) (not (cdr m)))))) - (define long-cmdline? (or (eq? (system-type) 'windows) - (eq? (system-type) 'macosx) + (define long-cmdline? (or (eq? (cross-system-type) 'windows) + (eq? (cross-system-type) 'macosx) unix-starter?)) (define relative? (let ([m (assq 'relative? aux)]) (and m (cdr m)))) (define collects-path-bytes (collects-path->bytes ((if (and mred? - (eq? 'macosx (system-type))) + (eq? 'macosx (cross-system-type))) mac-mred-collects-path-adjust values) collects-path))) @@ -1417,7 +1418,7 @@ (eprintf "Copying to ~s\n" dest)) (let-values ([(dest-exe orig-exe osx?) (cond - [(and mred? (eq? 'macosx (system-type))) + [(and mred? (eq? 'macosx (cross-system-type))) (values (prepare-macosx-mred exe dest aux variant) (mac-dest->executable (build-path (find-lib-dir) "Starter.app") #t) @@ -1452,7 +1453,7 @@ (delete-file dest))) (raise x))]) (define old-perms (ensure-writable dest-exe)) - (when (and (eq? 'macosx (system-type)) + (when (and (eq? 'macosx (cross-system-type)) (not unix-starter?)) (let ([m (or (assq 'framework-root aux) (and relative? '(framework-root . #f)))]) @@ -1475,7 +1476,7 @@ "/") dest mred?)))))) - (when (eq? 'windows (system-type)) + (when (eq? 'windows (cross-system-type)) (let ([m (or (assq 'dll-dir aux) (and relative? '(dll-dir . #f)))]) (if m @@ -1505,7 +1506,7 @@ ;; adjust relative path (since GRacket is off by one): (update-config-dir (mac-dest->executable dest mred?) "../../../etc/")] - [(eq? 'windows (system-type)) + [(eq? 'windows (cross-system-type)) (unless keep-exe? ;; adjust relative path (since GRacket is off by one): (update-config-dir dest "etc/"))]))) @@ -1539,7 +1540,7 @@ [decl-end-s (number->string decl-end)] [end-s (number->string end)]) (append (if launcher? - (if (and (eq? 'windows (system-type)) + (if (and (eq? 'windows (cross-system-type)) keep-exe?) ;; argv[0] replacement: (list (path->string @@ -1584,7 +1585,7 @@ (display "\0\0\0\0" out))]) (let-values ([(start decl-end end cmdline-end) (cond - [(eq? (system-type) 'windows) + [(eq? (cross-system-type) 'windows) ;; Add as a resource (define o (open-output-bytes)) (define decl-len (write-module o)) @@ -1604,7 +1605,7 @@ bstr)) (update-resources dest-exe pe new-rsrcs) (values 0 decl-len init-len (+ init-len cmdline-len))] - [(and (eq? (system-type) 'macosx) + [(and (eq? (cross-system-type) 'macosx) (not unix-starter?)) ;; For Mach-O, we know how to add a proper segment (define s (open-output-bytes)) @@ -1669,7 +1670,7 @@ [osx? ;; default path in `gracket' is off by one: (set-collects-path dest-exe #"../../../collects")] - [(eq? 'windows (system-type)) + [(eq? 'windows (cross-system-type)) (unless keep-exe? ;; off by one in this case, too: (set-collects-path dest-exe #"collects"))])]) @@ -1726,7 +1727,7 @@ "cmdline" #"\\[Replace me for EXE hack")))] [anotherpos (and mred? - (eq? 'windows (system-type)) + (eq? 'windows (cross-system-type)) (let ([m (assq 'single-instance? aux)]) (and m (not (cdr m)))) (with-input-from-file dest-exe @@ -1758,16 +1759,16 @@ (file-position out))]) (file-position out cmdpos) (fprintf out "~a...~a~a" - (if (and keep-exe? (eq? 'windows (system-type))) "*" "?") + (if (and keep-exe? (eq? 'windows (cross-system-type))) "*" "?") (integer->integer-bytes end 4 #t #f) (integer->integer-bytes (- new-end end) 4 #t #f))))) (lambda () (close-output-port out))) - (let ([m (and (eq? 'windows (system-type)) + (let ([m (and (eq? 'windows (cross-system-type)) (assq 'ico aux))]) (when m (replace-all-icos (read-icos (cdr m)) dest-exe))) - (let ([m (and (eq? 'windows (system-type)) + (let ([m (and (eq? 'windows (cross-system-type)) (assq 'subsystem aux))]) (when m (set-subsystem dest-exe (cdr m)))))])))) diff --git a/racket/collects/launcher/launcher.rkt b/racket/collects/launcher/launcher.rkt index 0cfec14e07..eb0b9fcda9 100644 --- a/racket/collects/launcher/launcher.rkt +++ b/racket/collects/launcher/launcher.rkt @@ -8,6 +8,7 @@ compiler/embed setup/dirs setup/variant + setup/cross-system compiler/private/winutf16) @@ -69,7 +70,7 @@ installed-desktop-path->icon-path) (define current-launcher-variant - (make-parameter (system-type 'gc) + (make-parameter (cross-system-type 'gc) (lambda (v) (unless (memq v '(3m script-3m cgc script-cgc)) (raise-type-error @@ -80,8 +81,8 @@ (define (variant-available? kind cased-kind-name variant) (cond - [(or (eq? 'unix (system-type)) - (and (eq? 'macosx (system-type)) + [(or (eq? 'unix (cross-system-type)) + (and (eq? 'macosx (cross-system-type)) (eq? kind 'mzscheme))) (let ([bin-dir (if (eq? kind 'mzscheme) (find-console-bin-dir) @@ -94,13 +95,13 @@ [(mzscheme) 'racket] [(mred) 'gracket]) (variant-suffix variant #f))))))] - [(eq? 'macosx (system-type)) + [(eq? 'macosx (cross-system-type)) ;; kind must be mred, because mzscheme case is caught above (directory-exists? (build-path (find-lib-dir) (format "~a~a.app" cased-kind-name (variant-suffix variant #f))))] - [(eq? 'windows (system-type)) + [(eq? 'windows (cross-system-type)) (file-exists? (build-path (if (eq? kind 'mzscheme) (find-console-bin-dir) (find-lib-dir)) @@ -111,7 +112,7 @@ (let* ([cased-kind-name (if (eq? kind 'mzscheme) "Racket" "GRacket")] - [normal-kind (system-type 'gc)] + [normal-kind (cross-system-type 'gc)] [alt-kind (if (eq? '3m normal-kind) 'cgc '3m)] @@ -121,7 +122,7 @@ [alt (if (variant-available? kind cased-kind-name alt-kind) (list alt-kind) null)] - [script (if (and (eq? 'macosx (system-type)) + [script (if (and (eq? 'macosx (cross-system-type)) (eq? kind 'mred) (pair? normal)) (if (eq? normal-kind '3m) @@ -167,7 +168,7 @@ (define (add-file-suffix path variant mred?) (let ([s (variant-suffix variant - (case (system-type) + (case (cross-system-type) [(unix) #f] [(windows) #t] [(macosx) (and mred? (not (script-variant? variant)))]))]) @@ -176,7 +177,7 @@ (path-replace-suffix path (string->bytes/utf-8 - (if (and (eq? 'windows (system-type)) + (if (and (eq? 'windows (cross-system-type)) (regexp-match #rx#"[.]exe$" (path->bytes path))) (format "~a.exe" s) s)))))) @@ -295,7 +296,7 @@ (define (has-exe? exe) (or (file-exists? (build-path "/usr/bin" exe)) (file-exists? (build-path "/bin" exe)))) - (let* ([has-readlink? (and (not (eq? 'macosx (system-type))) + (let* ([has-readlink? (and (not (eq? 'macosx (cross-system-type))) (has-exe? "readlink"))] [dest-explode (normalize+explode-path dest)] [bindir-explode (normalize+explode-path bindir)]) @@ -364,7 +365,7 @@ (cdr m) (variant-suffix variant #t) (cdr m) (variant-suffix variant #t))))] [x-flags? (and (eq? kind 'mred) - (eq? (system-type) 'unix) + (eq? (cross-system-type) 'unix) (not (script-variant? variant)))] [flags (let ([m (assq 'wm-class aux)]) (if m @@ -397,7 +398,7 @@ (if (and m (cdr m)) (find-lib-dir) (let ([p (path-only dest)]) - (if (eq? 'macosx (system-type)) + (if (eq? 'macosx (cross-system-type)) (build-path p 'up) p)))) (find-console-bin-dir))]) @@ -411,7 +412,7 @@ "librktdir" "bindir") (or alt-exe (case kind - [(mred) (if (eq? 'macosx (system-type)) + [(mred) (if (eq? 'macosx (cross-system-type)) (format "GRacket~a.app/Contents/MacOS/Gracket" (variant-suffix variant #t)) "gracket")] @@ -419,7 +420,7 @@ (if alt-exe "" (variant-suffix variant (and (eq? kind 'mred) - (eq? 'macosx (system-type))))) + (eq? 'macosx (cross-system-type))))) pre-str)] [args (format "~a~a ${1+\"$@\"}\n" @@ -516,7 +517,7 @@ extension)))) (define (check-desktop aux dest) - (when (eq? 'unix (system-type)) + (when (eq? 'unix (cross-system-type)) (let ([im (assoc 'install-mode aux)]) (when (and im (member (cdr im) '(main user))) (define user? (eq? (cdr im) 'user)) @@ -715,7 +716,7 @@ (close-output-port p))))) (define (get-maker) - (case (system-type) + (case (cross-system-type) [(unix) make-unix-launcher] [(windows) make-windows-launcher] [(macos) make-macos-launcher] @@ -880,7 +881,7 @@ (string-downcase (regexp-replace* #px"\\s" file "-"))) (define (sfx file mred?) - (case (system-type) + (case (cross-system-type) [(unix) (unix-sfx file mred?)] [(windows) (string-append (if mred? file (unix-sfx file mred?)) ".exe")] @@ -888,7 +889,7 @@ (define (program-launcher-path name mred? user?) (let* ([variant (current-launcher-variant)] - [mac-script? (and (eq? (system-type) 'macosx) + [mac-script? (and (eq? (cross-system-type) 'macosx) (script-variant? variant))]) (let ([p (add-file-suffix (build-path @@ -902,7 +903,7 @@ ((if mac-script? unix-sfx sfx) name mred?)) variant mred?)]) - (if (and (eq? (system-type) 'macosx) + (if (and (eq? (cross-system-type) 'macosx) (not (script-variant? variant))) (path-replace-suffix p #".app") p)))) @@ -913,7 +914,7 @@ (gracket-program-launcher-path name #:user? user?)) (define (racket-program-launcher-path name #:user? [user? #f]) - (case (system-type) + (case (cross-system-type) [(macosx) (add-file-suffix (build-path (if user? (find-user-console-bin-dir) @@ -935,7 +936,7 @@ #f) (define (gracket-launcher-is-actually-directory?) - (and (eq? 'macosx (system-type)) + (and (eq? 'macosx (cross-system-type)) (not (script-variant? (current-launcher-variant))))) (define (mred-launcher-is-actually-directory?) (gracket-launcher-is-actually-directory?)) @@ -963,16 +964,16 @@ (define (gracket-launcher-put-file-extension+style+filters) (put-file-extension+style+filters - (if (and (eq? 'macosx (system-type)) + (if (and (eq? 'macosx (cross-system-type)) (script-variant? (current-launcher-variant))) 'unix - (system-type)))) + (cross-system-type)))) (define (mred-launcher-put-file-extension+style+filters) (gracket-launcher-put-file-extension+style+filters)) (define (racket-launcher-put-file-extension+style+filters) (put-file-extension+style+filters - (if (eq? 'macosx (system-type)) 'unix (system-type)))) + (if (eq? 'macosx (cross-system-type)) 'unix (cross-system-type)))) (define (mzscheme-launcher-put-file-extension+style+filters) (racket-launcher-put-file-extension+style+filters)) @@ -991,7 +992,7 @@ ;; overwritten at that time. So we assume ;; that a Setup-PLT-style independent launcher ;; is always up-to-date. - [(eq? 'windows (system-type)) + [(eq? 'windows (cross-system-type)) (and (let ([m (assq 'independent? aux)]) (and m (cdr m))) (file-exists? dest))] ;; For any other setting, we could implement diff --git a/racket/collects/pkg/lib.rkt b/racket/collects/pkg/lib.rkt index 9cf0226ac2..f5589d499b 100644 --- a/racket/collects/pkg/lib.rkt +++ b/racket/collects/pkg/lib.rkt @@ -280,5 +280,5 @@ [pkg-directory->additional-installs (->* (path-string? string?) (#:namespace namespace? #:system-type (or/c #f symbol?) - #:system-library-subpath (or/c #f path?)) + #:system-library-subpath (or/c #f path-for-some-system?)) (listof (cons/c symbol? string?)))])) diff --git a/racket/collects/pkg/private/addl-installs.rkt b/racket/collects/pkg/private/addl-installs.rkt index 7fe41bfd95..d725eaeffa 100644 --- a/racket/collects/pkg/private/addl-installs.rkt +++ b/racket/collects/pkg/private/addl-installs.rkt @@ -111,6 +111,7 @@ (define v (i 'install-platform (lambda () #rx""))) (or (not (platform-spec? v)) (matching-platform? v + #:cross? #t #:system-type sys-type #:system-library-subpath sys-lib-subpath))) (set-union (extract-documents i) diff --git a/racket/collects/pkg/private/dep.rkt b/racket/collects/pkg/private/dep.rkt index 28a34eeb6c..5abdce4705 100644 --- a/racket/collects/pkg/private/dep.rkt +++ b/racket/collects/pkg/private/dep.rkt @@ -32,5 +32,5 @@ (define (dependency-this-platform? dep) (define p (dependency-lookup '#:platform dep)) - (or (not p) (matching-platform? p))) + (or (not p) (matching-platform? p #:cross? #t))) diff --git a/racket/collects/pkg/strip.rkt b/racket/collects/pkg/strip.rkt index 6c603b8bd4..6a40c01fad 100644 --- a/racket/collects/pkg/strip.rkt +++ b/racket/collects/pkg/strip.rkt @@ -9,6 +9,7 @@ racket/list racket/set racket/format + setup/cross-system setup/private/dylib setup/private/elf) @@ -425,11 +426,11 @@ (fixup uncopied))))) (unmove-tag 'move-foreign-libs find-user-lib-dir - (case (system-type) + (case (cross-system-type) [(macosx) adjust-dylib-path/uninstall] [else void]) - (case (system-type) + (case (cross-system-type) [(unix) copy-file/uninstall-elf-rpath] [else diff --git a/racket/collects/setup/cross-system.rkt b/racket/collects/setup/cross-system.rkt new file mode 100644 index 0000000000..1b1c565c25 --- /dev/null +++ b/racket/collects/setup/cross-system.rkt @@ -0,0 +1,77 @@ +#lang racket/base +(require "private/dirs.rkt") + +(provide cross-system-type + cross-system-library-subpath + cross-installation?) + +(define cross-system-table #f) + +(define system-type-symbols '(os word gc link machine so-suffix so-mode fs-change)) + +(define (compute-cross!) + (unless cross-system-table + (define lib-dir (find-lib-dir)) + (define ht (and lib-dir + (let ([f (build-path lib-dir "system.rktd")]) + (and (file-exists? f) + (let ([ht (call-with-input-file* + f + read)]) + (and (hash? ht) + (for/and ([sym (in-list (list* + 'library-subpath + 'library-subpath-convention + system-type-symbols))]) + (hash-ref ht sym #f)) + (not + (and (for/and ([sym (in-list system-type-symbols)] + #:unless (or (eq? sym 'machine) + (eq? sym 'gc))) + (equal? (hash-ref ht sym) (system-type sym))) + (equal? (bytes->path (hash-ref ht 'library-subpath) + (hash-ref ht 'library-subpath-convention)) + (system-library-subpath #f)))) + ht)))))) + (if ht + (set! cross-system-table ht) + (set! cross-system-table #hasheq())))) + +(define cross-system-type + (case-lambda + [() + (compute-cross!) + (or (hash-ref cross-system-table 'os #f) + (system-type 'os))] + [(mode) + (unless (memq mode system-type-symbols) + (raise-argument-error + 'cross-system-type + "(or/c 'os 'word 'gc 'link 'machine 'so-suffix 'so-mode 'fs-change)" + mode)) + (compute-cross!) + (or (hash-ref cross-system-table mode #f) + (system-type mode))])) + +(define (cross-system-library-subpath [mode (begin + (compute-cross!) + (cross-system-type 'gc))]) + (unless (memq mode '(#f 3m cgc)) + (raise-argument-error + 'cross-system-library-subtype + "(or/c #f '3m 'cgc)" + mode)) + (compute-cross!) + (define bstr (hash-ref cross-system-table 'library-subpath #f)) + (cond + [bstr + (define conv (hash-ref cross-system-table 'library-subpath-convention)) + (define path (bytes->path bstr conv)) + (case mode + [(#f cgc) path] + [(3m) (build-path path (bytes->path #"3m" conv))])] + [else (system-library-subpath mode)])) + +(define (cross-installation?) + (compute-cross!) + (positive? (hash-count cross-system-table))) diff --git a/racket/collects/setup/dirs.rkt b/racket/collects/setup/dirs.rkt index 6970af2ed8..f85c1bc45e 100644 --- a/racket/collects/setup/dirs.rkt +++ b/racket/collects/setup/dirs.rkt @@ -1,268 +1,15 @@ #lang racket/base - (require racket/promise compiler/private/winutf16 compiler/private/mach-o - '#%utils - (for-syntax racket/base)) + setup/cross-system + "private/dirs.rkt") -;; ---------------------------------------- -;; "config" - -(define (find-config-dir) - (find-main-config)) - -(provide find-config-dir) - -;; ---------------------------------------- -;; config: definitions - -(define config-table - (delay/sync - (let ([d (find-config-dir)]) - (if d - (let ([p (build-path d "config.rktd")]) - (if (file-exists? p) - (call-with-input-file* - p - (lambda (in) - (call-with-default-reading-parameterization - (lambda () - (read in))))) - #hash())) - #hash())))) - -(define (to-path l) - (cond [(string? l) (simplify-path (complete-path (string->path l)))] - [(bytes? l) (simplify-path (complete-path (bytes->path l)))] - [(list? l) (map to-path l)] - [else l])) - -(define (complete-path p) - (cond [(complete-path? p) p] - [else - (path->complete-path - p - (find-main-collects))])) - -(define-syntax-rule (define-config name key wrap) - (define name (delay/sync - (wrap - (hash-ref (force config-table) key #f))))) - -(define-config config:collects-search-dirs 'collects-search-dirs to-path) -(define-config config:doc-dir 'doc-dir to-path) -(define-config config:doc-search-dirs 'doc-search-dirs to-path) -(define-config config:dll-dir 'dll-dir to-path) -(define-config config:lib-dir 'lib-dir to-path) -(define-config config:lib-search-dirs 'lib-search-dirs to-path) -(define-config config:share-dir 'share-dir to-path) -(define-config config:apps-dir 'apps-dir to-path) -(define-config config:include-dir 'include-dir to-path) -(define-config config:include-search-dirs 'include-search-dirs to-path) -(define-config config:bin-dir 'bin-dir to-path) -(define-config config:man-dir 'man-dir to-path) -(define-config config:links-file 'links-file to-path) -(define-config config:links-search-files 'links-search-files to-path) -(define-config config:pkgs-dir 'pkgs-dir to-path) -(define-config config:pkgs-search-dirs 'pkgs-search-dirs to-path) -(define-config config:cgc-suffix 'cgc-suffix values) -(define-config config:3m-suffix '3m-suffix values) -(define-config config:absolute-installation? 'absolute-installation? (lambda (x) (and x #t))) -(define-config config:doc-search-url 'doc-search-url values) -(define-config config:doc-open-url 'doc-open-url values) -(define-config config:installation-name 'installation-name values) -(define-config config:build-stamp 'build-stamp values) - -(provide get-absolute-installation? - get-cgc-suffix - get-3m-suffix - get-doc-search-url - get-doc-open-url - get-installation-name - get-build-stamp) - -(define (get-absolute-installation?) (force config:absolute-installation?)) -(define (get-cgc-suffix) (force config:cgc-suffix)) -(define (get-3m-suffix) (force config:3m-suffix)) -(define (get-doc-search-url) (or (force config:doc-search-url) - "http://docs.racket-lang.org/local-redirect/index.html")) -(define (get-doc-open-url) (force config:doc-open-url)) -(define (get-installation-name) (or (force config:installation-name) - (version))) -(define (get-build-stamp) (force config:build-stamp)) - -;; ---------------------------------------- -;; "collects" - -(provide find-collects-dir - get-main-collects-search-dirs - find-user-collects-dir - get-collects-search-dirs) -(define (find-collects-dir) - (find-main-collects)) -(define (get-main-collects-search-dirs) - (combine-search (force config:collects-search-dirs) - (list (find-collects-dir)))) -(define user-collects-dir - (delay/sync (simplify-path (build-path (find-system-path 'addon-dir) - (get-installation-name) - "collects")))) -(define (find-user-collects-dir) - (force user-collects-dir)) -(define (get-collects-search-dirs) - (current-library-collection-paths)) - -;; ---------------------------------------- -;; Helpers - -(define (single p) (if p (list p) null)) -(define (extra a l) (if (and a (not (member (path->directory-path a) - (map path->directory-path l)))) - (append l (list a)) - l)) -(define (combine-search l default) - ;; Replace #f in list with default path: - (if l - (let loop ([l l]) - (cond - [(null? l) null] - [(not (car l)) (append default (loop (cdr l)))] - [else (cons (car l) (loop (cdr l)))])) - default)) -(define (cons-user u r) - (if (and u (use-user-specific-search-paths)) - (cons u r) - r)) -(define (get-false) #f) -(define (chain-to f) f) - -(define-syntax (define-finder stx) - (syntax-case stx (get-false chain-to) - [(_ provide config:id id user-id #:default user-default default) - #' - (begin - (define-finder provide config:id id get-false default) - (provide user-id) - (define user-dir - (delay/sync (simplify-path (build-path (find-system-path 'addon-dir) - (get-installation-name) - user-default)))) - (define (user-id) - (force user-dir)))] - [(_ provide config:id id user-id config:search-id search-id default) - #' - (begin - (define-finder provide config:id id user-id default) - (provide search-id) - (define (search-id) - (combine-search (force config:search-id) - (cons-user (user-id) (single (id))))))] - [(_ provide config:id id user-id config:search-id search-id - extra-search-dir default) - #' - (begin - (define-finder provide config:id id user-id default) - (provide search-id) - (define (search-id) - (combine-search (force config:search-id) - (extra (extra-search-dir) - (cons-user (user-id) (single (id)))))))] - [(_ provide config:id id get-false (chain-to get-default)) - (with-syntax ([dir (generate-temporaries #'(id))]) - #'(begin - (provide id) - (define dir - (delay/sync - (or (force config:id) (get-default)))) - (define (id) - (force dir))))] - [(_ provide config:id id get-false default) - (with-syntax ([dir (generate-temporaries #'(id))]) - #'(begin - (provide id) - (define dir - (delay/sync - (or (force config:id) - (let ([p (find-collects-dir)]) - (and p (simplify-path (build-path p 'up default))))))) - (define (id) - (force dir))))] - [(_ provide config:id id user-id default) - #'(define-finder provide config:id id user-id #:default default default)])) - -(define-syntax no-provide (syntax-rules () [(_ . rest) (begin)])) - -;; ---------------------------------------- -;; "doc" - -(define delayed-#f (delay/sync #f)) - -(provide find-doc-dir - find-user-doc-dir - get-doc-search-dirs) -(define-finder no-provide - config:doc-dir - find-doc-dir - find-user-doc-dir - delayed-#f - get-new-doc-search-dirs - "doc") -;; For now, include "doc" pseudo-collections in search path: -(define (get-doc-search-dirs) - (combine-search (force config:doc-search-dirs) - (append (get-new-doc-search-dirs) - (map (lambda (p) (build-path p "doc")) - (current-library-collection-paths))))) - -;; ---------------------------------------- -;; "include" - -(define-finder provide - config:include-dir - find-include-dir - find-user-include-dir - config:include-search-dirs - get-include-search-dirs - "include") - -;; ---------------------------------------- -;; "lib" - -(define-finder provide - config:lib-dir - find-lib-dir - find-user-lib-dir - config:lib-search-dirs - get-lib-search-dirs - "lib") - -;; ---------------------------------------- -;; "share" - -(define-finder provide - config:share-dir - find-share-dir - find-user-share-dir - "share") - -;; ---------------------------------------- -;; "apps" - -(define-finder provide - config:apps-dir - find-apps-dir - find-user-apps-dir #:default (build-path "share" "applications") - (chain-to (lambda () (build-path (find-share-dir) "applications")))) - -;; ---------------------------------------- -;; "man" - -(define-finder provide - config:man-dir - find-man-dir - find-user-man-dir - "man") +(provide (except-out (all-from-out "private/dirs.rkt") + config:dll-dir + config:bin-dir + define-finder) + find-dll-dir) ;; ---------------------------------------- ;; Executables @@ -271,7 +18,7 @@ config:bin-dir find-console-bin-dir find-user-console-bin-dir - (case (system-type) + (case (cross-system-type) [(windows) 'same] [(macosx unix) "bin"])) @@ -279,7 +26,7 @@ config:bin-dir find-gui-bin-dir find-user-gui-bin-dir - (case (system-type) + (case (cross-system-type) [(windows macosx) 'same] [(unix) "bin"])) @@ -289,106 +36,77 @@ (provide find-dll-dir) (define dll-dir (delay/sync - (case (system-type) + (case (cross-system-type) [(windows) - ;; Extract "lib" location from binary: - (let ([exe (parameterize ([current-directory (find-system-path 'orig-dir)]) - (find-executable-path (find-system-path 'exec-file)))]) - (and - exe - (with-input-from-file exe - (lambda () - (let ([m (regexp-match (byte-regexp - (bytes-append - (bytes->utf-16-bytes #"dLl dIRECTORy:") - #"((?:..)*?)\0\0")) - (current-input-port))]) - (unless m - (error "cannot find \"dLl dIRECTORy\" tag in binary")) - (let-values ([(dir name dir?) (split-path exe)]) - (if (regexp-match #rx#"^<" (cadr m)) - ;; no DLL dir in binary - #f - ;; resolve relative directory: - (let ([p (bytes->path (utf-16-bytes->bytes (cadr m)))]) - (path->complete-path p dir)))))))))] + (if (eq? (system-type) 'windows) + ;; Extract "lib" location from binary: + (let ([exe (parameterize ([current-directory (find-system-path 'orig-dir)]) + (find-executable-path (find-system-path 'exec-file)))]) + (and + exe + (with-input-from-file exe + (lambda () + (let ([m (regexp-match (byte-regexp + (bytes-append + (bytes->utf-16-bytes #"dLl dIRECTORy:") + #"((?:..)*?)\0\0")) + (current-input-port))]) + (unless m + (error "cannot find \"dLl dIRECTORy\" tag in binary")) + (let-values ([(dir name dir?) (split-path exe)]) + (if (regexp-match #rx#"^<" (cadr m)) + ;; no DLL dir in binary + #f + ;; resolve relative directory: + (let ([p (bytes->path (utf-16-bytes->bytes (cadr m)))]) + (path->complete-path p dir))))))))) + ;; Cross-compile: assume it's "lib" + (find-lib-dir))] [(macosx) - (let* ([exe (parameterize ([current-directory (find-system-path 'orig-dir)]) - (let loop ([p (find-executable-path - (find-system-path 'exec-file))]) - (and - p - (if (link-exists? p) - (loop (let-values ([(r) (resolve-path p)] - [(dir name dir?) (split-path p)]) - (if (and (path? dir) - (relative-path? r)) - (build-path dir r) - r))) - p))))] - [rel (and exe - (let ([l (get/set-dylib-path exe "Racket" #f)]) - (if (null? l) - #f - (car l))))]) - (cond - [(not rel) #f] ; no framework reference found!? - [(regexp-match - #rx#"^(@executable_path/)?(.*?)G?Racket.framework" - rel) - => (lambda (m) - (let ([b (caddr m)]) - (if (and (not (cadr m)) (bytes=? b #"")) - #f ; no path in exe - (simplify-path - (path->complete-path - (if (not (cadr m)) - (bytes->path b) - (let-values ([(dir name dir?) (split-path exe)]) - (if (bytes=? b #"") - dir - (build-path dir (bytes->path b))))) - (find-system-path 'orig-dir))))))] - [else (find-lib-dir)]))] + (if (eq? (system-type) 'macosx) + (let* ([exe (parameterize ([current-directory (find-system-path 'orig-dir)]) + (let loop ([p (find-executable-path + (find-system-path 'exec-file))]) + (and + p + (if (link-exists? p) + (loop (let-values ([(r) (resolve-path p)] + [(dir name dir?) (split-path p)]) + (if (and (path? dir) + (relative-path? r)) + (build-path dir r) + r))) + p))))] + [rel (and exe + (let ([l (get/set-dylib-path exe "Racket" #f)]) + (if (null? l) + #f + (car l))))]) + (cond + [(not rel) #f] ; no framework reference found!? + [(regexp-match + #rx#"^(@executable_path/)?(.*?)G?Racket.framework" + rel) + => (lambda (m) + (let ([b (caddr m)]) + (if (and (not (cadr m)) (bytes=? b #"")) + #f ; no path in exe + (simplify-path + (path->complete-path + (if (not (cadr m)) + (bytes->path b) + (let-values ([(dir name dir?) (split-path exe)]) + (if (bytes=? b #"") + dir + (build-path dir (bytes->path b))))) + (find-system-path 'orig-dir))))))] + [else (find-lib-dir)])) + ;; Cross-compile: assume it's "lib" + (find-lib-dir))] [else - (if (eq? 'shared (system-type 'link)) + (if (eq? 'shared (cross-system-type 'link)) (or (force config:dll-dir) (find-lib-dir)) #f)]))) (define (find-dll-dir) (force dll-dir)) -;; ---------------------------------------- -;; Links files - -(provide find-links-file - get-links-search-files - find-user-links-file) - -(define (find-links-file) - (or (force config:links-file) - (build-path (find-share-dir) "links.rktd"))) -(define (get-links-search-files) - (combine-search (force config:links-search-files) - (list (find-links-file)))) - -(define (find-user-links-file [vers (get-installation-name)]) - (build-path (find-system-path 'addon-dir) - vers - "links.rktd")) - -;; ---------------------------------------- -;; Packages - -(define-finder provide - config:pkgs-dir - find-pkgs-dir - get-false - config:pkgs-search-dirs - get-pkgs-search-dirs - (chain-to (lambda () (build-path (find-share-dir) "pkgs")))) - -(provide find-user-pkgs-dir) -(define (find-user-pkgs-dir [vers (get-installation-name)]) - (build-path (find-system-path 'addon-dir) - vers - "pkgs")) diff --git a/racket/collects/setup/matching-platform.rkt b/racket/collects/setup/matching-platform.rkt index 9e89e022b2..ca13f3fd3e 100644 --- a/racket/collects/setup/matching-platform.rkt +++ b/racket/collects/setup/matching-platform.rkt @@ -1,4 +1,5 @@ #lang racket/base +(require setup/cross-system) (provide platform-spec? matching-platform?) @@ -7,20 +8,27 @@ (or (symbol? p) (string? p) (regexp? p))) (define (matching-platform? p + #:cross? [cross? #f] #:system-type [sys-type #f] #:system-library-subpath [sys-lib-subpath #f]) (unless (platform-spec? p) (raise-argument-error 'matching-platform? "platform-spec?" p)) (unless (or (not sys-type) (symbol? sys-type)) (raise-argument-error 'matching-platform? "(or/c symbol? #f)" sys-type)) - (unless (or (not sys-lib-subpath) (path? sys-lib-subpath)) - (raise-argument-error 'matching-platform? "(or/c path? #f)" sys-lib-subpath)) + (unless (or (not sys-lib-subpath) (path-for-some-system? sys-lib-subpath)) + (raise-argument-error 'matching-platform? "(or/c path-for-some-system? #f)" sys-lib-subpath)) (cond [(symbol? p) - (eq? p (or sys-type (system-type)))] + (eq? p (or sys-type (if cross? + (cross-system-type) + (system-type))))] [else - (define s (path->string (or sys-lib-subpath - (system-library-subpath #f)))) + (define s (bytes->string/utf-8 + (path->bytes + (or sys-lib-subpath + (if cross? + (cross-system-library-subpath #f) + (system-library-subpath #f)))))) (cond [(regexp? p) (regexp-match? p s)] diff --git a/racket/collects/setup/parallel-do.rkt b/racket/collects/setup/parallel-do.rkt index 4d6d37b73c..fb2b4c4658 100644 --- a/racket/collects/setup/parallel-do.rkt +++ b/racket/collects/setup/parallel-do.rkt @@ -9,6 +9,7 @@ racket/path racket/class racket/stxparam + setup/dirs (for-syntax syntax/parse racket/base)) @@ -73,7 +74,10 @@ (define/public (spawn _id _module-path _funcname [initialmsg #f]) (set! module-path _module-path) (set! funcname _funcname) - (define worker-cmdline-list (list (current-executable-path) "-X" (path->string (current-collects-path)) "-e" "(eval(read))")) + (define worker-cmdline-list (list (current-executable-path) + "-X" (path->string (current-collects-path)) + "-G" (path->string (find-config-dir)) + "-e" "(eval(read))")) (define dynamic-require-cmd `((dynamic-require (string->path ,module-path) (quote ,funcname)) #f)) (let-values ([(_process-handle _out _in _err) (apply subprocess #f #f (current-error-port) worker-cmdline-list)]) (set! id _id) diff --git a/racket/collects/setup/private/dirs.rkt b/racket/collects/setup/private/dirs.rkt new file mode 100644 index 0000000000..4ad0e241bd --- /dev/null +++ b/racket/collects/setup/private/dirs.rkt @@ -0,0 +1,314 @@ +#lang racket/base +(require racket/promise + '#%utils + (for-syntax racket/base)) + +;; ---------------------------------------- +;; "config" + +(define (find-config-dir) + (find-main-config)) + +(provide find-config-dir) + +;; ---------------------------------------- +;; config: definitions + +(define config-table + (delay/sync + (let ([d (find-config-dir)]) + (if d + (let ([p (build-path d "config.rktd")]) + (if (file-exists? p) + (call-with-input-file* + p + (lambda (in) + (call-with-default-reading-parameterization + (lambda () + (read in))))) + #hash())) + #hash())))) + +(define (to-path l) + (cond [(string? l) (simplify-path (complete-path (string->path l)))] + [(bytes? l) (simplify-path (complete-path (bytes->path l)))] + [(list? l) (map to-path l)] + [else l])) + +(define (complete-path p) + (cond [(complete-path? p) p] + [else + (path->complete-path + p + (find-main-collects))])) + +(define-syntax-rule (define-config name key wrap) + (define name (delay/sync + (wrap + (hash-ref (force config-table) key #f))))) + +(define-config config:collects-search-dirs 'collects-search-dirs to-path) +(define-config config:doc-dir 'doc-dir to-path) +(define-config config:doc-search-dirs 'doc-search-dirs to-path) +(define-config config:dll-dir 'dll-dir to-path) +(define-config config:lib-dir 'lib-dir to-path) +(define-config config:lib-search-dirs 'lib-search-dirs to-path) +(define-config config:share-dir 'share-dir to-path) +(define-config config:apps-dir 'apps-dir to-path) +(define-config config:include-dir 'include-dir to-path) +(define-config config:include-search-dirs 'include-search-dirs to-path) +(define-config config:bin-dir 'bin-dir to-path) +(define-config config:man-dir 'man-dir to-path) +(define-config config:links-file 'links-file to-path) +(define-config config:links-search-files 'links-search-files to-path) +(define-config config:pkgs-dir 'pkgs-dir to-path) +(define-config config:pkgs-search-dirs 'pkgs-search-dirs to-path) +(define-config config:cgc-suffix 'cgc-suffix values) +(define-config config:3m-suffix '3m-suffix values) +(define-config config:absolute-installation? 'absolute-installation? (lambda (x) (and x #t))) +(define-config config:doc-search-url 'doc-search-url values) +(define-config config:doc-open-url 'doc-open-url values) +(define-config config:installation-name 'installation-name values) +(define-config config:build-stamp 'build-stamp values) + +(provide get-absolute-installation? + get-cgc-suffix + get-3m-suffix + get-doc-search-url + get-doc-open-url + get-installation-name + get-build-stamp) + +(define (get-absolute-installation?) (force config:absolute-installation?)) +(define (get-cgc-suffix) (force config:cgc-suffix)) +(define (get-3m-suffix) (force config:3m-suffix)) +(define (get-doc-search-url) (or (force config:doc-search-url) + "http://docs.racket-lang.org/local-redirect/index.html")) +(define (get-doc-open-url) (force config:doc-open-url)) +(define (get-installation-name) (or (force config:installation-name) + (version))) +(define (get-build-stamp) (force config:build-stamp)) + +;; ---------------------------------------- +;; "collects" + +(provide find-collects-dir + get-main-collects-search-dirs + find-user-collects-dir + get-collects-search-dirs) +(define (find-collects-dir) + (find-main-collects)) +(define (get-main-collects-search-dirs) + (combine-search (force config:collects-search-dirs) + (list (find-collects-dir)))) +(define user-collects-dir + (delay/sync (simplify-path (build-path (find-system-path 'addon-dir) + (get-installation-name) + "collects")))) +(define (find-user-collects-dir) + (force user-collects-dir)) +(define (get-collects-search-dirs) + (current-library-collection-paths)) + +;; ---------------------------------------- +;; Helpers + +(define (single p) (if p (list p) null)) +(define (extra a l) (if (and a (not (member (path->directory-path a) + (map path->directory-path l)))) + (append l (list a)) + l)) +(define (combine-search l default) + ;; Replace #f in list with default path: + (if l + (let loop ([l l]) + (cond + [(null? l) null] + [(not (car l)) (append default (loop (cdr l)))] + [else (cons (car l) (loop (cdr l)))])) + default)) +(define (cons-user u r) + (if (and u (use-user-specific-search-paths)) + (cons u r) + r)) +(define (get-false) #f) +(define (chain-to f) f) + +(define-syntax (define-finder stx) + (syntax-case stx (get-false chain-to) + [(_ provide config:id id user-id #:default user-default default) + #' + (begin + (define-finder provide config:id id get-false default) + (provide user-id) + (define user-dir + (delay/sync (simplify-path (build-path (find-system-path 'addon-dir) + (get-installation-name) + user-default)))) + (define (user-id) + (force user-dir)))] + [(_ provide config:id id user-id config:search-id search-id default) + #' + (begin + (define-finder provide config:id id user-id default) + (provide search-id) + (define (search-id) + (combine-search (force config:search-id) + (cons-user (user-id) (single (id))))))] + [(_ provide config:id id user-id config:search-id search-id + extra-search-dir default) + #' + (begin + (define-finder provide config:id id user-id default) + (provide search-id) + (define (search-id) + (combine-search (force config:search-id) + (extra (extra-search-dir) + (cons-user (user-id) (single (id)))))))] + [(_ provide config:id id get-false (chain-to get-default)) + (with-syntax ([dir (generate-temporaries #'(id))]) + #'(begin + (provide id) + (define dir + (delay/sync + (or (force config:id) (get-default)))) + (define (id) + (force dir))))] + [(_ provide config:id id get-false default) + (with-syntax ([dir (generate-temporaries #'(id))]) + #'(begin + (provide id) + (define dir + (delay/sync + (or (force config:id) + (let ([p (find-collects-dir)]) + (and p (simplify-path (build-path p 'up default))))))) + (define (id) + (force dir))))] + [(_ provide config:id id user-id default) + #'(define-finder provide config:id id user-id #:default default default)])) + +(define-syntax no-provide (syntax-rules () [(_ . rest) (begin)])) + +(provide define-finder) + +;; ---------------------------------------- +;; "doc" + +(define delayed-#f (delay/sync #f)) + +(provide find-doc-dir + find-user-doc-dir + get-doc-search-dirs) +(define-finder no-provide + config:doc-dir + find-doc-dir + find-user-doc-dir + delayed-#f + get-new-doc-search-dirs + "doc") +;; For now, include "doc" pseudo-collections in search path: +(define (get-doc-search-dirs) + (combine-search (force config:doc-search-dirs) + (append (get-new-doc-search-dirs) + (map (lambda (p) (build-path p "doc")) + (current-library-collection-paths))))) + +;; ---------------------------------------- +;; "include" + +(define-finder provide + config:include-dir + find-include-dir + find-user-include-dir + config:include-search-dirs + get-include-search-dirs + "include") + +;; ---------------------------------------- +;; "lib" + +(define-finder provide + config:lib-dir + find-lib-dir + find-user-lib-dir + config:lib-search-dirs + get-lib-search-dirs + "lib") + +;; ---------------------------------------- +;; "share" + +(define-finder provide + config:share-dir + find-share-dir + find-user-share-dir + "share") + +;; ---------------------------------------- +;; "apps" + +(define-finder provide + config:apps-dir + find-apps-dir + find-user-apps-dir #:default (build-path "share" "applications") + (chain-to (lambda () (build-path (find-share-dir) "applications")))) + +;; ---------------------------------------- +;; "man" + +(define-finder provide + config:man-dir + find-man-dir + find-user-man-dir + "man") + +;; ---------------------------------------- +;; Executables + +;; `setup/dirs` + +(provide config:bin-dir) + +;; ---------------------------------------- +;; DLLs + +;; See `setup/dirs` + +(provide config:dll-dir) + +;; ---------------------------------------- +;; Links files + +(provide find-links-file + get-links-search-files + find-user-links-file) + +(define (find-links-file) + (or (force config:links-file) + (build-path (find-share-dir) "links.rktd"))) +(define (get-links-search-files) + (combine-search (force config:links-search-files) + (list (find-links-file)))) + +(define (find-user-links-file [vers (get-installation-name)]) + (build-path (find-system-path 'addon-dir) + vers + "links.rktd")) + +;; ---------------------------------------- +;; Packages + +(define-finder provide + config:pkgs-dir + find-pkgs-dir + get-false + config:pkgs-search-dirs + get-pkgs-search-dirs + (chain-to (lambda () (build-path (find-share-dir) "pkgs")))) + +(provide find-user-pkgs-dir) +(define (find-user-pkgs-dir [vers (get-installation-name)]) + (build-path (find-system-path 'addon-dir) + vers + "pkgs")) diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index 12303c5342..909f2707a6 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -15,6 +15,7 @@ planet/planet-archives planet/private/planet-shared (only-in planet/resolver resolve-planet-path) + setup/cross-system "option.rkt" compiler/compiler @@ -880,7 +881,7 @@ (string? v) (symbol? v)) (error "entry is not regexp, string, or symbol:" v))))) - (matching-platform? sys)) + (matching-platform? sys #:cross? #t)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Make zo ;; @@ -1407,7 +1408,7 @@ [(console) (path->relative-string/console-bin p)] [else (error 'make-launcher "internal error (~s)" kind)]) (let ([v (current-launcher-variant)]) - (if (eq? v (system-type 'gc)) "" (format " [~a]" v)))) + (if (eq? v (cross-system-type 'gc)) "" (format " [~a]" v)))) (make-launcher (or mzlf (if (cc-collection cc) @@ -1563,7 +1564,7 @@ (setup-printf "deleting" "launcher ~a" rel-exe-path) (delete-directory/files exe-path)]) ;; Clean up any associated .desktop file and icon file: - (when (eq? 'unix (system-type)) + (when (eq? 'unix (cross-system-type)) (let ([desktop (installed-executable-path->desktop-path exe-path user?)]) @@ -1780,11 +1781,11 @@ (error "entry is not a list of relative path strings:" l))) build-path this-platform? - (case (system-type) + (case (cross-system-type) [(macosx) adjust-dylib-path/install] [else void]) - (case (system-type) + (case (cross-system-type) [(unix) copy-file/install-elf-rpath] [else copy-file]))) @@ -1905,7 +1906,8 @@ ;; setup Body ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (setup-printf "version" "~a [~a]" (version) (system-type 'gc)) + (setup-printf "version" "~a" (version)) + (setup-printf "platform" "~a [~a]" (cross-system-library-subpath #f) (cross-system-type 'gc)) (setup-printf "installation name" "~a" (get-installation-name)) (setup-printf "variants" "~a" (string-join (map symbol->string (available-mzscheme-variants)) ", ")) (setup-printf "main collects" "~a" main-collects-dir) @@ -1943,7 +1945,7 @@ (when (make-launchers) (make-launchers-step)) (when (make-launchers) - (unless (eq? 'windows (system-type)) + (unless (eq? 'windows (cross-system-type)) (make-mans-step))) (when make-docs? diff --git a/racket/collects/setup/variant.rkt b/racket/collects/setup/variant.rkt index 09ead3e51e..01969f5044 100644 --- a/racket/collects/setup/variant.rkt +++ b/racket/collects/setup/variant.rkt @@ -1,23 +1,29 @@ #lang racket/base -(require setup/dirs racket/promise) +(require setup/dirs + setup/cross-system + racket/promise) (provide variant-suffix) (define plain-mz-is-cgc? (delay/sync - (let* ([dir (find-console-bin-dir)] - [exe (cond [(eq? 'windows (system-type)) "Racket.exe"] - [(equal? #".dll" (system-type 'so-suffix)) - ;; in cygwin so-suffix is ".dll" - "racket.exe"] - [else "racket"])] - [f (build-path dir exe)]) - (and (file-exists? f) - (with-input-from-file f - (lambda () - (regexp-match? #rx#"bINARy tYPe:..c" - (current-input-port)))))))) + (cond + [(cross-installation?) + (eq? 'cgc (cross-system-type 'gc))] + [else + (let* ([dir (find-console-bin-dir)] + [exe (cond [(eq? 'windows (system-type)) "Racket.exe"] + [(equal? #".dll" (system-type 'so-suffix)) + ;; in cygwin so-suffix is ".dll" + "racket.exe"] + [else "racket"])] + [f (build-path dir exe)]) + (and (file-exists? f) + (with-input-from-file f + (lambda () + (regexp-match? #rx#"bINARy tYPe:..c" + (current-input-port))))))]))) (define (variant-suffix variant cased?) (let ([r (case variant diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 7c27d9b68a..1efdba7a87 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -86,6 +86,10 @@ common: $(MAKE) @FOREIGNTARGET@ cgc: + $(MAKE) cgc-core + $(MAKE) sysinfer@CGC@ + +cgc-core: $(MAKE) common $(MAKE) dynlib $(MAKE) mzlibrary @@ -98,9 +102,10 @@ cgc: cd dynsrc; $(MAKE) dynlib3m cd gc2; $(MAKE) ../racket@MMM@ cd gc2; $(MAKE) ../mzcom@MMM@ + $(MAKE) sysinfer@MMM@ both: - $(MAKE) cgc + $(MAKE) cgc-core $(MAKE) 3m oskit: @@ -157,6 +162,16 @@ no-cgc-needed: $(MAKE) mingw-other cd dynsrc; $(MAKE) ../starter@EXE_SUFFIX@ +ALL_CPPFLAGS = -I$(builddir) -I$(srcdir)/include -I$(srcdir)/src $(CPPFLAGS) @OPTIONS@ @GC2OPTIONS@ @MZOPTIONS@ +MKSYSTEM_ARGS = -cqu $(srcdir)/mksystem.rkt system.rktd "$(CPP) $(ALL_CPPFLAGS) $(srcdir)/src/systype.c" "@MMM_INSTALLED@" + +sysinfer@CGC@: + @RUN_RACKET_CGC@ $(MKSYSTEM_ARGS) "@RUN_RACKET_CGC@" "$(RUN_THIS_RACKET_CGC)" + +sysinfer@MMM@: + @RUN_RACKET_MMM@ $(MKSYSTEM_ARGS) "@RUN_RACKET_MMM@" "$(RUN_THIS_RACKET_MMM)" + + FOREIGN_USED_LIB = $(FOREIGN_OBJ) $(FOREIGN_LIB) FOREIGN_USED_OBJSLIB = $(FOREIGN_OBJSLIB) FOREIGN_NOT_USED_LIB = $(FOREIGN_OBJ) @@ -305,6 +320,7 @@ total_startup: headers: @RUN_RACKET_CGC@ -cqu $(srcdir)/mkincludes.rkt @DIRCVTPRE@"$(DESTDIR)$(includepltdir)"@DIRCVTPOST@ "$(srcdir)" . + cd ..; cp racket/system.rktd "$(DESTDIR)$(libpltdir)/system.rktd" $(srcdir)/src/schexn.h: $(srcdir)/src/makeexn $(RACKET) -um $(srcdir)/src/makeexn > $(srcdir)/src/schexn.h diff --git a/racket/src/racket/gc2/Makefile.in b/racket/src/racket/gc2/Makefile.in index 2e33b27767..42fb655448 100644 --- a/racket/src/racket/gc2/Makefile.in +++ b/racket/src/racket/gc2/Makefile.in @@ -292,7 +292,7 @@ $(XSRCDIR)/setjmpup.c: $(XFORMDEP) $(XFORM) $(XSRCDIR)/setjmpup.c $(SRCDIR)/setjmpup.c $(XSRCDIR)/sfs.c: $(XFORMDEP) $(XFORM) $(XSRCDIR)/sfs.c $(SRCDIR)/sfs.c -$(XSRCDIR)/string.c: $(XFORMDEP) +$(XSRCDIR)/string.c: $(XFORMDEP) $(SRCDIR)/systype.inc $(XFORM_SETUP) --cpp "$(CPP) -I../src $(ALL_CPPFLAGS)" @XFORMFLAGS@ -o $(XSRCDIR)/string.c $(SRCDIR)/string.c $(XSRCDIR)/struct.c: $(XFORMDEP) $(XFORM) $(XSRCDIR)/struct.c $(SRCDIR)/struct.c diff --git a/racket/src/racket/mksystem.rkt b/racket/src/racket/mksystem.rkt new file mode 100644 index 0000000000..67713ba1d6 --- /dev/null +++ b/racket/src/racket/mksystem.rkt @@ -0,0 +1,75 @@ +(module mkincludes '#%kernel + (#%require '#%min-stx) + ;; Arguments are + ;; [ <3m-exe-suffix> ] + (define-values (args) (current-command-line-arguments)) + + (define-values (ht) + (if (or (= (vector-length args) 1) + (equal? (vector-ref args (- (vector-length args) 1)) + (vector-ref args (- (vector-length args) 2)))) + ;; Not cross-compiling + (hash 'os (system-type 'os) + 'word (system-type 'word) + 'gc (if (= (vector-length args) 1) + '3m ; GC mode for suffixless executables + (if (string=? "" (vector-ref args 2)) + '3m + 'cgc)) + 'link (system-type 'link) + 'machine (bytes->string/utf-8 (path->bytes (system-library-subpath #f))) + 'so-suffix (system-type 'so-suffix) + 'so-mode (system-type 'so-mode) + 'fs-change (system-type 'fs-change) + 'library-subpath (path->bytes (system-library-subpath #f)) + 'library-subpath-convention (system-path-convention-type)) + ;; Cross-compiling; use `cpp` to get details + (begin + (printf "Extracting system information for cross-compile\n") + (let-values ([(p out in err) + (subprocess #f #f #f "/bin/sh" "-c" (vector-ref args 1))]) + (close-output-port in) + (letrec-values ([(read-all) (lambda () + (let-values ([(s) (read-bytes 4096 out)]) + (if (eof-object? s) + #"" + (bytes-append s (read-all)))))]) + (let-values ([(expanded) (read-all)]) + (let-values ([(get-string) + (lambda (var) + (let-values ([(m) (regexp-match (string-append " " var " = ([^\n;]*);") + expanded)]) + (if m + (bytes->string/utf-8 + (regexp-replace* #rx"\\\\\\\\" + (regexp-replace* #rx"^\"|\" *\"|\"$" (cadr m) "") + "\\\\")) + (error 'mksystem "not found in cpp output: ~e" var))))]) + (let-values ([(get-symbol) + (lambda (var) (string->symbol (get-string var)))] + [(get-int) + (lambda (var) (string->number (get-string var)))]) + (let-values ([(library-subpath) + (get-string "system_library_subpath")] + [(os) (get-symbol "system_type_os")]) + (hash 'os os + 'word (* 8 (get-int "system_pointer_size")) + 'gc (if (string=? "" (vector-ref args 2)) + '3m + 'cgc) + 'link (get-symbol "system_type_link") + 'machine library-subpath + 'so-suffix (string->bytes/utf-8 (get-string "system_type_so_suffix")) + 'so-mode (get-symbol "system_type_so_mode") + 'fs-change '#(#f #f #f #f) + 'library-subpath (string->bytes/utf-8 library-subpath) + 'library-subpath-convention (if (eq? os 'windows) + 'windows + 'unix))))))))))) + + (call-with-output-file + (vector-ref args 0) + (lambda (o) + (write ht o) + (newline o)) + 'truncate/replace)) diff --git a/racket/src/racket/src/Makefile.in b/racket/src/racket/src/Makefile.in index e47890dfb0..6be8335605 100644 --- a/racket/src/racket/src/Makefile.in +++ b/racket/src/racket/src/Makefile.in @@ -419,7 +419,7 @@ sfs.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/stypes.h $(srcdir)/mzmark_sfs.inc string.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/stypes.h $(srcdir)/schvers.h $(srcdir)/mzmark_string.inc $(srcdir)/strops.inc \ - $(srcdir)/schustr.inc + $(srcdir)/schustr.inc $(srcdir)/systype.inc struct.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/stypes.h $(srcdir)/mzmark_struct.inc syntax.@LTO@: $(COMMON_HEADERS) \ diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 403bb94c3b..25734056ff 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.10" +#define MZSCHEME_VERSION "6.2.900.11" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 10 +#define MZSCHEME_VERSION_W 11 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/string.c b/racket/src/racket/src/string.c index abb3544a5a..f794a5d324 100644 --- a/racket/src/racket/src/string.c +++ b/racket/src/racket/src/string.c @@ -2723,23 +2723,13 @@ void *scheme_environment_variables_to_block(Scheme_Object *ev, int *_need_free) static void machine_details(char *s); +#include "systype.inc" + static Scheme_Object *system_type(int argc, Scheme_Object *argv[]) { if (argc) { if (SAME_OBJ(argv[0], link_symbol)) { -#if defined(OS_X) && !defined(XONX) - return scheme_intern_symbol("framework"); -#else -# ifdef DOS_FILE_SYSTEM - return scheme_intern_symbol("dll"); -# else -# ifdef MZ_USES_SHARED_LIB - return scheme_intern_symbol("shared"); -# else - return scheme_intern_symbol("static"); -# endif -# endif -#endif + return scheme_intern_symbol(MZ_SYSTEM_TYPE_LINK); } if (SAME_OBJ(argv[0], machine_symbol)) { @@ -2759,27 +2749,11 @@ static Scheme_Object *system_type(int argc, Scheme_Object *argv[]) } if (SAME_OBJ(argv[0], so_suffix_symbol)) { -#ifdef DOS_FILE_SYSTEM - return scheme_make_byte_string(".dll"); -#else -# ifdef OS_X - return scheme_make_byte_string(".dylib"); -# else -# ifdef USE_CYGWIN_SO_SUFFIX - return scheme_make_byte_string(".dll"); -# else - return scheme_make_byte_string(".so"); -# endif -# endif -#endif + return scheme_make_byte_string(MZ_SYSTEM_TYPE_SO_SUFFIX); } if (SAME_OBJ(argv[0], so_mode_symbol)) { -#ifdef USE_DLOPEN_GLOBAL_BY_DEFAULT - return scheme_intern_symbol("global"); -#else - return scheme_intern_symbol("local"); -#endif + return scheme_intern_symbol(MZ_SYSTEM_TYPE_SO_MODE); } diff --git a/racket/src/racket/src/systype.c b/racket/src/racket/src/systype.c new file mode 100644 index 0000000000..fb75a14a5d --- /dev/null +++ b/racket/src/racket/src/systype.c @@ -0,0 +1,16 @@ +/* This file is run through `cpp` by "../mysystem.rkt" + in cross-compilation mode. */ + +#include "schpriv.h" +#include "systype.inc" +#ifndef SCHEME_PLATFORM_LIBRARY_SUBPATH +# include "schsys.h" +#endif + +string system_type_os = SYSTEM_TYPE_NAME; +string system_type_link = MZ_SYSTEM_TYPE_LINK; +string system_type_so_suffix = MZ_SYSTEM_TYPE_SO_SUFFIX; +string system_type_so_mode = MZ_SYSTEM_TYPE_SO_MODE; +string system_library_subpath = SCHEME_PLATFORM_LIBRARY_SUBPATH; + +int system_pointer_size = SIZEOF_VOID_P; diff --git a/racket/src/racket/src/systype.inc b/racket/src/racket/src/systype.inc new file mode 100644 index 0000000000..448d5fb088 --- /dev/null +++ b/racket/src/racket/src/systype.inc @@ -0,0 +1,37 @@ + +/* Some answers for `system-type`, also consulted for cross-compilation */ + +#if defined(OS_X) && !defined(XONX) +# define MZ_SYSTEM_TYPE_LINK "framework" +#else +# ifdef DOS_FILE_SYSTEM +# define MZ_SYSTEM_TYPE_LINK "dll" +# else +# ifdef MZ_USES_SHARED_LIB +# define MZ_SYSTEM_TYPE_LINK "shared" +# else +# define MZ_SYSTEM_TYPE_LINK "static" +# endif +# endif +#endif + +#ifdef DOS_FILE_SYSTEM +# define MZ_SYSTEM_TYPE_SO_SUFFIX ".dll" +#else +# ifdef OS_X +# define MZ_SYSTEM_TYPE_SO_SUFFIX ".dylib" +# else +# ifdef USE_CYGWIN_SO_SUFFIX +# define MZ_SYSTEM_TYPE_SO_SUFFIX ".dll" +# else +# define MZ_SYSTEM_TYPE_SO_SUFFIX ".so" +# endif +# endif +#endif + + +#ifdef USE_DLOPEN_GLOBAL_BY_DEFAULT +# define MZ_SYSTEM_TYPE_SO_MODE "global" +#else +# define MZ_SYSTEM_TYPE_SO_MODE "local" +#endif diff --git a/racket/src/worksp/gc2/make.rkt b/racket/src/worksp/gc2/make.rkt index 057a04584c..b6f09a35e1 100644 --- a/racket/src/worksp/gc2/make.rkt +++ b/racket/src/worksp/gc2/make.rkt @@ -413,3 +413,6 @@ (copy-file/diff "mzdyn3m.exp" "../../../lib/msvc/mzdyn3m.exp") (copy-file/diff "mzdyn3m.obj" "../../../lib/msvc/mzdyn3m.obj") + +(parameterize ([current-command-line-arguments (vector "../../../lib/system.rktd")]) + (dynamic-require "../../racket/mksystem.rkt" #f)) diff --git a/racket/src/worksp/racket/racket.vcproj b/racket/src/worksp/racket/racket.vcproj index cb07b21109..6461624e1c 100644 --- a/racket/src/worksp/racket/racket.vcproj +++ b/racket/src/worksp/racket/racket.vcproj @@ -60,7 +60,7 @@ /> From 4eeb164d31e7fdeb9b72afaebe63f9b03f1ea61a Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 27 Aug 2015 14:24:05 -0500 Subject: [PATCH 111/381] Remove dependency on unstable/flonum. --- pkgs/racket-test-core/tests/racket/math.rktl | 47 +++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/math.rktl b/pkgs/racket-test-core/tests/racket/math.rktl index 4a0dab02ec..17a931e34b 100644 --- a/pkgs/racket-test-core/tests/racket/math.rktl +++ b/pkgs/racket-test-core/tests/racket/math.rktl @@ -2,7 +2,52 @@ (Section 'math) (require scheme/math racket/flonum - unstable/flonum) + racket/unsafe/ops) + +(define (flonum->bit-field x) + (cond [(flonum? x) (integer-bytes->integer (real->floating-point-bytes x 8) #f)] + [else (raise-type-error 'flonum->bit-field "flonum" x)])) + +(define (bit-field->flonum i) + (cond [(and (exact-integer? i) (i . >= . 0) (i . <= . #xffffffffffffffff)) + (floating-point-bytes->real (integer->integer-bytes i 8 #f))] + [else + (raise-type-error 'bit-field->flonum "exact integer in [0,#xffffffffffffffff]" i)])) + +(define (flonum->ordinal x) + (cond [(flonum? x) (cond [(x . < . 0) (- (flonum->bit-field (- x)))] + [else (flonum->bit-field (unsafe-flabs x))])] ; abs for -0.0 + [else (raise-type-error 'flonum->ordinal "flonum" x)])) + +(define (ordinal->flonum i) + (cond [(and (exact-integer? i) (i . >= . #x-7fffffffffffffff) (i . <= . #x7fffffffffffffff)) + (cond [(i . < . 0) (- (bit-field->flonum (- i)))] + [else (bit-field->flonum i)])] + [else + (raise-type-error + 'ordinal->flonum "exact integer in [#x-7fffffffffffffff,#xffffffffffffffff]" i)])) + +(define +inf-ordinal (flonum->ordinal +inf.0)) +(define -inf-ordinal (flonum->ordinal -inf.0)) + +(define (flstep x n) + (cond [(not (flonum? x)) (raise-type-error 'flstep "flonum" 0 x n)] + [(not (exact-integer? n)) (raise-type-error 'flstep "exact integer" 1 x n)] + [(eqv? x +nan.0) +nan.0] + [(and (eqv? x +inf.0) (n . >= . 0)) +inf.0] + [(and (eqv? x -inf.0) (n . <= . 0)) -inf.0] + [else (define i (+ n (flonum->ordinal x))) + (cond [(i . < . -inf-ordinal) -inf.0] + [(i . > . +inf-ordinal) +inf.0] + [else (ordinal->flonum i)])])) + +(define (flnext x) (flstep x 1)) +(define (flprev x) (flstep x -1)) + +(define -max.0 (flnext -inf.0)) +(define -min.0 (flprev 0.0)) +(define +min.0 (flnext 0.0)) +(define +max.0 (flprev +inf.0)) (define (double=? x y) (and (flonum? y) From d71832f20ebeb05bf6f5998f8a840d65977aade2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 27 Aug 2015 14:34:49 -0600 Subject: [PATCH 112/381] another MSVC MzCOM repair Missed a line that was meant to be included with commit a98947e81e. --- racket/src/mzcom/mzobj.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/mzcom/mzobj.cxx b/racket/src/mzcom/mzobj.cxx index 698988656f..e928f293d5 100644 --- a/racket/src/mzcom/mzobj.cxx +++ b/racket/src/mzcom/mzobj.cxx @@ -308,6 +308,7 @@ static int record_at_exit(Scheme_At_Exit_Callback_Proc p) XFORM_SKIP_PROC return 0; } +#define NO_TLS_INDEX_FOR_WIN_TLS 1 #include "../racket/win_tls.inc" static unsigned WINAPI evalLoop(void *args) XFORM_SKIP_PROC { From a6e42858f4b1e0fcf31827f021b22c7604255ce5 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 27 Aug 2015 17:01:19 -0500 Subject: [PATCH 113/381] add a commented out specialization of (-> void) This is the most common contract created for -> (at 318 occurrences out of the 6515 arrow contracts created when DrRacket starts up) but this specialization doesn't seem to actually improve the performance much. Leave it in for now, in case the story changes at some point in the future --- .../contract/private/arrow-val-first.rkt | 71 ++++++++++++++----- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 5ac0e6de1f..92159a55bf 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -68,7 +68,6 @@ (generate-popular-key-ids popular-key-ids) (define-for-syntax (build-plus-one-arity-function+chaperone-constructor - stx regular-args optional-args mandatory-kwds @@ -294,7 +293,6 @@ [else (loop (cdr optional-args) (cdr ob) #f)])))) - (cond [(null? (cdr case-lambda-clauses)) ;; need to specialize this case because @@ -546,7 +544,7 @@ [rng (add-pos-obligations (list #'rng))])) (define-values (plus-one-arity-function chaperone-constructor) (build-plus-one-arity-function+chaperone-constructor - stx regular-args '() kwds '() #f #f #f rngs #f #f)) + regular-args '() kwds '() #f #f #f rngs #f #f)) (syntax-property #`(let #,let-bindings #,(quasisyntax/loc stx @@ -671,7 +669,6 @@ (list))]) (define-values (plus-one-arity-function chaperone-constructor) (build-plus-one-arity-function+chaperone-constructor - stx (syntax->list #'(mandatory-dom ...)) (syntax->list #'(optional-dom ...)) (syntax->list #'(mandatory-dom-kwd ...)) @@ -767,19 +764,35 @@ (and raw-rngs (for/list ([rng (in-list raw-rngs)]) (coerce-contract who rng)))) - (if (and (andmap chaperone-contract? regular-doms) - (andmap (λ (x) (chaperone-contract? (kwd-info-ctc x))) kwd-infos) - (andmap chaperone-contract? (or rngs '()))) - (make--> (length raw-regular-doms) - regular-doms kwd-infos rest-ctc pre-cond - rngs post-cond - plus-one-arity-function - chaperone-constructor) - (make-impersonator-> (length raw-regular-doms) - regular-doms kwd-infos rest-ctc pre-cond - rngs post-cond - plus-one-arity-function - chaperone-constructor))) + (cond + ;; uncomment this to specialize (-> void) contract to a + ;; more efficient wrapper (but there are no test cases for + ;; that code, so add them before pushing this) + #; + [(and (null? regular-doms) + (null? kwd-infos) + (not rest-ctc) + (not pre-cond) + (not post-cond) + (pair? rngs) + (null? (cdr rngs)) + (flat-contract? (car rngs)) + (eq? void? (flat-contract-predicate (car rngs)))) + ->void-contract] + [(and (andmap chaperone-contract? regular-doms) + (andmap (λ (x) (chaperone-contract? (kwd-info-ctc x))) kwd-infos) + (andmap chaperone-contract? (or rngs '()))) + (make--> (length raw-regular-doms) + regular-doms kwd-infos rest-ctc pre-cond + rngs post-cond + plus-one-arity-function + chaperone-constructor)] + [else + (make-impersonator-> (length raw-regular-doms) + regular-doms kwd-infos rest-ctc pre-cond + rngs post-cond + plus-one-arity-function + chaperone-constructor)])) (define (dynamic->* #:mandatory-domain-contracts [mandatory-domain-contracts '()] #:optional-domain-contracts [optional-domain-contracts '()] @@ -1178,3 +1191,27 @@ #:property prop:contract (make-property build-contract-property impersonate-procedure)) + +(define ->void-contract + (let-syntax ([get-chaperone-constructor + (λ (_) + ;; relies on the popular key (0 0 () () #f 1) appearing first + (define ids (list-ref popular-key-ids 0)) + (list-ref ids 1))]) + (make--> 0 '() '() #f #f + (list (coerce-contract 'whatever void?)) + #f + (λ (blame f _ignored-rng-contract) + (λ (neg-party) + (call-with-values + (λ () (f)) + (case-lambda + [(rng) + (unless (void? rng) + (raise-blame-error blame #:missing-party neg-party rng + '(expected: "void?" given: "~e") + rng)) + rng] + [args + (wrong-number-of-results-blame blame neg-party f args 1)])))) + (get-chaperone-constructor)))) From 460743021df9c673a07f067614a9bebd34d0b78b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 13:30:43 -0600 Subject: [PATCH 114/381] fix over-counting of place-message channel memory --- racket/src/racket/gc2/mem_account.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 1f1565a2a7..abf104b406 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -371,8 +371,8 @@ int BTC_bi_chan_mark(void *p, struct NewGC *gc) /* Race conditions here on `mem_size', and likely double counting when the same async channels are accessible from paired bi channels --- but those approximations are ok for accounting. */ - account_memory(gc, gc->current_mark_owner, bc->link->sendch->mem_size, 0); - account_memory(gc, gc->current_mark_owner, bc->link->recvch->mem_size, 0); + account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->sendch->mem_size), 0); + account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->recvch->mem_size), 0); } return gc->mark_table[btc_redirect_bi_chan](p, gc); } From 2773737c9cae2340d129a710586e155c5da90ae6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 15:32:53 -0600 Subject: [PATCH 115/381] avoid races in marking shared-space objects Although the race condition for setting mark bits shouldn't matter, reasoning about the race is difficult and asking for trouble, so don't do it. --- racket/src/racket/gc2/newgc.c | 34 ++++++++++++++++++++++++++++------ racket/src/racket/gc2/newgc.h | 3 +++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 8d43b52140..9ac503c3e0 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2952,7 +2952,7 @@ static void sync_master_progress(NewGC *gc, int done, Log_Master_Info *lmi) { } else { int i = 0; int alive = MASTERGCINFO->alive; - /* wake everyone back up, except MASTERGC and ourself */ + /* wake everyone back up, except MASTERGC and ourself */ for (i = 2; i < alive; i++) { mzrt_sema_post(MASTERGCINFO->wait_go_sema); } @@ -3369,11 +3369,11 @@ static void promote_marked_gen0_big_page(NewGC *gc, mpage *page) { #endif } -static void mark_recur_or_push_ptr(struct NewGC *gc, void *p) +static void mark_recur_or_push_ptr(struct NewGC *gc, void *p, int is_a_master_page) { objhead *ohead = OBJPTR_TO_OBJHEAD(p); - if (gc->mark_depth < MAX_RECUR_MARK_DEPTH) { + if ((gc->mark_depth < MAX_RECUR_MARK_DEPTH) && !is_a_master_page) { switch (ohead->type) { case PAGE_TAGGED: { @@ -3406,6 +3406,20 @@ static void mark_recur_or_push_ptr(struct NewGC *gc, void *p) push_ptr(gc, p); } +#ifdef MZ_USE_PLACES +static void adjust_page_lock(int is_a_master_page, mpage *page, intptr_t prev, intptr_t next) +{ + if (is_a_master_page) { + while (!mzrt_cas(&page->page_lock, prev, next)) { /* spin! */ } + } +} +# define TAKE_PAGE_LOCK(is_a_master_page, page) adjust_page_lock(is_a_master_page, page, 0, 1); +# define RELEASE_PAGE_LOCK(is_a_master_page, page) adjust_page_lock(is_a_master_page, page, 1, 0); +#else +# define TAKE_PAGE_LOCK(is_a_master_page, page) /* empty */ +# define RELEASE_PAGE_LOCK(is_a_master_page, page) /* empty */ +#endif + /* This is the first mark routine. It's a bit complicated. */ void GC_mark2(const void *const_p, struct NewGC *gc) { @@ -3433,10 +3447,13 @@ void GC_mark2(const void *const_p, struct NewGC *gc) } } + TAKE_PAGE_LOCK(is_a_master_page, page); + #ifdef NEWGC_BTC_ACCOUNT /* toss this over to the BTC mark routine if we're doing accounting */ if(gc->doing_memory_accounting) { BTC_memory_account_mark(gc, page, p, is_a_master_page); + RELEASE_PAGE_LOCK(is_a_master_page, page); return; } #endif @@ -3449,6 +3466,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) previously */ if (page->size_class != 2) { GCDEBUG((DEBUGOUTF, "Not marking %p on big %p (already marked)\n", p, page)); + RELEASE_PAGE_LOCK(is_a_master_page, page); return; } /* in this case, it has not. So we want to mark it, first off. */ @@ -3469,6 +3487,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) objhead *info = MED_OBJHEAD(p, page->size); if (info->mark) { GCDEBUG((DEBUGOUTF,"Not marking %p (already marked)\n", p)); + RELEASE_PAGE_LOCK(is_a_master_page, page); return; } info->mark = 1; @@ -3476,7 +3495,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) p = OBJHEAD_TO_OBJPTR(info); backtrace_new_page_if_needed(gc, page); record_backtrace(gc, page, p); - mark_recur_or_push_ptr(gc, p); + mark_recur_or_push_ptr(gc, p, is_a_master_page); } } /* SMALL_PAGE from gen0 or gen1 */ @@ -3485,6 +3504,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) if(ohead->mark) { GCDEBUG((DEBUGOUTF,"Not marking %p (already marked)\n", p)); + RELEASE_PAGE_LOCK(is_a_master_page, page); return; } @@ -3503,7 +3523,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) page->previous_size = PREFIX_SIZE; page->live_size += ohead->size; record_backtrace(gc, page, p); - mark_recur_or_push_ptr(gc, p); + mark_recur_or_push_ptr(gc, p, is_a_master_page); } else { GCDEBUG((DEBUGOUTF, "Not marking %p (it's old; %p / %i)\n", p, page, page->previous_size)); } @@ -3608,10 +3628,12 @@ void GC_mark2(const void *const_p, struct NewGC *gc) /* set forwarding pointer */ GCDEBUG((DEBUGOUTF,"Marking %p (moved to %p on page %p)\n", p, newp, work)); *(void**)p = newp; - mark_recur_or_push_ptr(gc, newp); + mark_recur_or_push_ptr(gc, newp, is_a_master_page); } } } + + RELEASE_PAGE_LOCK(is_a_master_page, page); } void GC_mark(const void *const_p) diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 6668b8016d..e73cbb09b3 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -29,6 +29,9 @@ typedef struct mpage { void *backtrace_page_src; #endif void *mmu_src_block; +#ifdef MZ_USE_PLACES + uintptr_t page_lock; /* for master GC pages during marking */ +#endif } mpage; typedef struct Gen0 { From a9078196b741beb0899edb831f751964cad7f499 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 15:57:42 -0600 Subject: [PATCH 116/381] fix GC problem with in-flight place messages While a place message is received by a thread but not yet deserialized, if the message contains references to objects in the shared space, and if a "master" GC happens (which crosses all places), make sure that the references in the still-serialized message are traversed. --- .../tests/racket/place-chmsg-gc-acct.rkt | 27 +++++++++ racket/src/racket/include/scheme.h | 1 + racket/src/racket/src/mzmark_type.inc | 20 +++++++ racket/src/racket/src/mzmarksrc.c | 10 ++++ racket/src/racket/src/place.c | 55 +++++++++++++------ 5 files changed, 96 insertions(+), 17 deletions(-) create mode 100644 pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt diff --git a/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt b/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt new file mode 100644 index 0000000000..1bcb74dce5 --- /dev/null +++ b/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt @@ -0,0 +1,27 @@ +#lang racket/base +(require racket/place) + +(define (go) + (place + pch + + ;; Trigger memory accounting in every place: + #; + (custodian-limit-memory + (current-custodian) + (* 1024 1024 1024)) + + (dynamic-require 'tests/racket/place-chmsg-gc #f) + + 0)) + +(module+ main + (define r + (map place-wait + (for/list ([i 8]) + (go)))) + (unless (andmap zero? r) + (error "some place failed"))) + + + diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 71f7620a31..e2f3222f93 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1261,6 +1261,7 @@ typedef struct Scheme_Thread { #ifdef MZ_PRECISE_GC struct GC_Thread_Info *gc_info; /* managed by the GC */ void *place_channel_msg_in_flight; + void *place_channel_msg_chain_in_flight; #endif } Scheme_Thread; diff --git a/racket/src/racket/src/mzmark_type.inc b/racket/src/racket/src/mzmark_type.inc index 1e35671a42..605e38e480 100644 --- a/racket/src/racket/src/mzmark_type.inc +++ b/racket/src/racket/src/mzmark_type.inc @@ -1890,6 +1890,16 @@ static int thread_val_MARK(void *p, struct NewGC *gc) { gcMARK2(pr->mbox_first, gc); gcMARK2(pr->mbox_last, gc); gcMARK2(pr->mbox_sema, gc); + + /* Follow msg_chain for an in-flight message like in place_async_channel_val */ + { + Scheme_Object *cpr = pr->place_channel_msg_chain_in_flight; + while (cpr) { + gcMARK2(SCHEME_CAR(cpr), gc); + cpr = SCHEME_CDR(cpr); + } + } + return gcBYTES_TO_WORDS(sizeof(Scheme_Thread)); } @@ -2008,6 +2018,16 @@ static int thread_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(pr->mbox_first, gc); gcFIXUP2(pr->mbox_last, gc); gcFIXUP2(pr->mbox_sema, gc); + + /* Follow msg_chain for an in-flight message like in place_async_channel_val */ + { + Scheme_Object *cpr = pr->place_channel_msg_chain_in_flight; + while (cpr) { + gcFIXUP2(SCHEME_CAR(cpr), gc); + cpr = SCHEME_CDR(cpr); + } + } + return gcBYTES_TO_WORDS(sizeof(Scheme_Thread)); } diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 3a05bbc505..7e56ae0bbe 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -797,6 +797,16 @@ thread_val { gcMARK2(pr->mbox_first, gc); gcMARK2(pr->mbox_last, gc); gcMARK2(pr->mbox_sema, gc); + + /* Follow msg_chain for an in-flight message like in place_async_channel_val */ + { + Scheme_Object *cpr = pr->place_channel_msg_chain_in_flight; + while (cpr) { + gcMARK2(SCHEME_CAR(cpr), gc); + cpr = SCHEME_CDR(cpr); + } + } + size: gcBYTES_TO_WORDS(sizeof(Scheme_Thread)); } diff --git a/racket/src/racket/src/place.c b/racket/src/racket/src/place.c index cb7c64eac3..c17c84f42c 100644 --- a/racket/src/racket/src/place.c +++ b/racket/src/racket/src/place.c @@ -1288,10 +1288,10 @@ static Scheme_Object *trivial_copy(Scheme_Object *so, Scheme_Object **master_cha if (SHARED_ALLOCATEDP(so)) { scheme_hash_key(so); if (master_chain) { - /* Keep track of all the master-allocated objects that are - in a message, so that the corresponding objects can be - marked during a master GC, in case on happens before the - message is received. */ + /* Keep track of all the objects that are in a message that + refer to master-allocated objects, so that the + corresponding objects can be marked during a master GC, + in case one happens before the message is received. */ Scheme_Object *mc; mc = scheme_make_raw_pair(so, *master_chain); *master_chain = mc; @@ -3504,12 +3504,14 @@ static void lock_and_register_place_object_with_channel(Scheme_Place_Async_Chann } } -static Scheme_Object *place_async_try_receive_raw(Scheme_Place_Async_Channel *ch, void **msg_memory_ptr, +static Scheme_Object *place_async_try_receive_raw(Scheme_Place_Async_Channel *ch, + void **msg_memory_ptr, + void **msg_chain_ptr, int *_no_writers) /* The result must not be retained past extraction from `*msg_memory_ptr'! */ { Scheme_Object *msg = NULL; - void *msg_memory = NULL; + void *msg_memory = NULL, *msg_chain = NULL; intptr_t sz; lock_and_register_place_object_with_channel(ch, (Scheme_Object *) place_object); @@ -3517,11 +3519,14 @@ static Scheme_Object *place_async_try_receive_raw(Scheme_Place_Async_Channel *ch if (ch->count > 0) { /* GET MSG */ msg = ch->msgs[ch->out]; msg_memory = ch->msg_memory[ch->out]; + msg_chain = ch->msg_chains[ch->out]; ch->msgs[ch->out] = NULL; ch->msg_memory[ch->out] = NULL; ch->msg_chains[ch->out] = NULL; + /* No GCs from here until msg_chain is registered */ + --ch->count; ch->out = ((ch->out + 1) % ch->size); @@ -3535,13 +3540,9 @@ static Scheme_Object *place_async_try_receive_raw(Scheme_Place_Async_Channel *ch *_no_writers = 1; mzrt_mutex_unlock(ch->lock); - if (msg) { - intptr_t msg_size; - msg_size = GC_message_allocator_size(msg_memory); - log_place_event("id %d: get message of %" PRIdPTR " bytes", "get", 1, msg_size); - } - *msg_memory_ptr = msg_memory; + *msg_chain_ptr = msg_chain; + return msg; } @@ -3550,19 +3551,33 @@ static void cleanup_msg_memmory(void *thread) { if (p->place_channel_msg_in_flight) { GC_destroy_orphan_msg_memory(p->place_channel_msg_in_flight); p->place_channel_msg_in_flight = NULL; + p->place_channel_msg_chain_in_flight = NULL; + } +} + +static void log_received_msg(Scheme_Object *msg, void *msg_memory) +{ + if (msg) { + intptr_t msg_size; + msg_size = GC_message_allocator_size(msg_memory); + log_place_event("id %d: get message of %" PRIdPTR " bytes", "get", 1, msg_size); } } static Scheme_Object *place_async_try_receive(Scheme_Place_Async_Channel *ch, int *_no_writers) { Scheme_Object *msg = NULL; Scheme_Thread *p = scheme_current_thread; - GC_CAN_IGNORE void *msg_memory; + GC_CAN_IGNORE void *msg_memory, *msg_chain; BEGIN_ESCAPEABLE(cleanup_msg_memmory, p); - msg = place_async_try_receive_raw(ch, &msg_memory, _no_writers); + msg = place_async_try_receive_raw(ch, &msg_memory, &msg_chain, _no_writers); + /* no GCs until msg_chain is registered */ if (msg) { p->place_channel_msg_in_flight = msg_memory; + p->place_channel_msg_chain_in_flight = msg_chain; + log_received_msg(msg, msg_memory); msg = scheme_places_deserialize(msg, msg_memory); p->place_channel_msg_in_flight = NULL; + p->place_channel_msg_chain_in_flight = NULL; } END_ESCAPEABLE(); return msg; @@ -3589,6 +3604,7 @@ static Scheme_Object *place_channel_finish_ready(void *d, int argc, struct Schem BEGIN_ESCAPEABLE(cleanup_msg_memmory, p); msg = scheme_places_deserialize(msg, p->place_channel_msg_in_flight); p->place_channel_msg_in_flight = NULL; + p->place_channel_msg_chain_in_flight = NULL; END_ESCAPEABLE(); return msg; @@ -3598,7 +3614,7 @@ static int place_channel_ready(Scheme_Object *so, Scheme_Schedule_Info *sinfo) { Scheme_Place_Bi_Channel *ch; Scheme_Object *msg = NULL; Scheme_Object *wrapper; - void *msg_memory = NULL; + GC_CAN_IGNORE void *msg_memory = NULL, *msg_chain = NULL; int no_writers = 0; if (SAME_TYPE(SCHEME_TYPE(so), scheme_place_type)) { @@ -3609,18 +3625,23 @@ static int place_channel_ready(Scheme_Object *so, Scheme_Schedule_Info *sinfo) { } msg = place_async_try_receive_raw((Scheme_Place_Async_Channel *) ch->link->recvch, - &msg_memory, &no_writers); + &msg_memory, &msg_chain, &no_writers); + /* no GCs until msg_chain is registered */ if (msg != NULL) { Scheme_Object **msg_holder; Scheme_Thread *p = ((Syncing *)(sinfo->current_syncing))->thread; + p->place_channel_msg_in_flight = msg_memory; + p->place_channel_msg_chain_in_flight = msg_chain; + + log_received_msg(msg, msg_memory); + /* Hold `msg' in atomic memory, because we're not allowed to hold onto it beyond release of msg_memory, and `wrapper' and the result flow into the evt system in general. */ msg_holder = (Scheme_Object **)scheme_malloc_atomic(sizeof(Scheme_Object*)); *msg_holder = msg; - p->place_channel_msg_in_flight = msg_memory; wrapper = scheme_make_closed_prim(place_channel_finish_ready, msg_holder); scheme_set_sync_target(sinfo, scheme_void, wrapper, NULL, 0, 0, NULL); From b016246096ff8eb67d522a29d2279bead2d29923 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 16:38:05 -0600 Subject: [PATCH 117/381] avoid interferences among places for memory accounting All places uses the same accounting bit for objects that are in the shared space. Each place also flips the bit value it wants on each accounting, so if two places are accounting at the same time with opposite bit values and can reach the same objects, they can interefere. It's even possible for them to race through cycles and cause each other to loop forever. Add a lock to ensure that there's only one bit value in play for the shared space at any given time. A place must stall if other places are busy with memory accounting and an opposite bit value. --- .../tests/racket/place-chmsg-gc-acct.rkt | 1 - racket/src/racket/gc2/mem_account.c | 81 ++++++++++++++++++- racket/src/racket/gc2/newgc.c | 31 +++---- racket/src/racket/gc2/newgc.h | 1 + 4 files changed, 95 insertions(+), 19 deletions(-) diff --git a/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt b/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt index 1bcb74dce5..b03e788d2a 100644 --- a/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt +++ b/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt @@ -6,7 +6,6 @@ pch ;; Trigger memory accounting in every place: - #; (custodian-limit-memory (current-custodian) (* 1024 1024 1024)) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index abf104b406..dee0990d92 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -268,15 +268,85 @@ inline static uintptr_t custodian_usage(NewGC*gc, void *custodian) return gcWORDS_TO_BYTES(retval); } +#ifdef MZ_USE_PLACES + +static mzrt_mutex *master_btc_lock; +static mzrt_sema *master_btc_sema; +static int master_btc_lock_count = 0; +static int master_btc_lock_waiters = 0; + +void init_master_btc_locks() +{ + mzrt_mutex_create(&master_btc_lock); + mzrt_sema_create(&master_btc_sema, 0); +} + +static void check_master_btc_mark(NewGC *gc, mpage *page) +{ + if (!gc->master_page_btc_mark_checked) { + int pause = 1; + RELEASE_PAGE_LOCK(1, page); + while (pause) { + mzrt_mutex_lock(master_btc_lock); + if (master_btc_lock_count + && (gc->new_btc_mark != MASTERGC->new_btc_mark)) { + pause = 1; + master_btc_lock_waiters++; + } else { + pause = 0; + MASTERGC->new_btc_mark = gc->new_btc_mark; + master_btc_lock_count++; + } + mzrt_mutex_unlock(master_btc_lock); + + if (pause) + mzrt_sema_wait(master_btc_sema); + } + TAKE_PAGE_LOCK(1, page); + gc->master_page_btc_mark_checked = 1; + } +} + +static void release_master_btc_mark(NewGC *gc) +{ + if (gc->master_page_btc_mark_checked) { + /* release the lock on the master's new_btc_mark value */ + mzrt_mutex_lock(master_btc_lock); + --master_btc_lock_count; + if (!master_btc_lock_count && master_btc_lock_waiters) { + --master_btc_lock_waiters; + mzrt_sema_post(master_btc_sema); + } + mzrt_mutex_unlock(master_btc_lock); + } +} + +#else + +static void check_master_btc_mark(NewGC *gc) { } +static void release_master_btc_mark(NewGC *gc) { } + +#endif + inline static void BTC_memory_account_mark(NewGC *gc, mpage *page, void *ptr, int is_a_master_page) { GCDEBUG((DEBUGOUTF, "BTC_memory_account_mark: %p/%p\n", page, ptr)); /* In the case of is_a_master_page, whether this place is charged is - a little random: there's no guarantee that the btc_mark values are - in sync, and there are races among places. Approximations are ok for - accounting, though, as long as the probably for completely wrong - accounting is very low. */ + a little random: there's no guarantee that the btc_mark values + are in sync, and there are races among places. Approximations are + ok for accounting, though, as long as the probably for completely + wrong accounting is very low. + + At the same time, we need to synchronize enough so that two + places with different new_btc_mark values don't send each other + into infinite loops (with the btc_mark value bouncing back and + forth) or overcounting. We synchronize enough by having a single + new_btc_mark value for master pages, and we stall if the value + isn't what this place wants. */ + + if (is_a_master_page) + check_master_btc_mark(gc, page); if(page->size_class) { if(page->size_class > 1) { @@ -427,6 +497,7 @@ static void BTC_do_accounting(NewGC *gc) gc->doing_memory_accounting = 1; gc->in_unsafe_allocation_mode = 1; gc->unsafe_allocation_abort = btc_overmem_abort; + gc->master_page_btc_mark_checked = 0; /* clear the memory use numbers out */ for(i = 1; i < table_size; i++) @@ -468,6 +539,8 @@ static void BTC_do_accounting(NewGC *gc) gc->phantom_count = save_count; } + release_master_btc_mark(gc); + /* walk backward folding totals int parent */ cur = last; while (cur) { diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 9ac503c3e0..ca08b0d627 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -178,6 +178,20 @@ struct Log_Master_Info { # define PLACES_AND(v) 0 #endif +#ifdef MZ_USE_PLACES +static void adjust_page_lock(int is_a_master_page, mpage *page, intptr_t prev, intptr_t next) +{ + if (is_a_master_page) { + while (!mzrt_cas(&page->page_lock, prev, next)) { /* spin! */ } + } +} +# define TAKE_PAGE_LOCK(is_a_master_page, page) adjust_page_lock(is_a_master_page, page, 0, 1); +# define RELEASE_PAGE_LOCK(is_a_master_page, page) adjust_page_lock(is_a_master_page, page, 1, 0); +#else +# define TAKE_PAGE_LOCK(is_a_master_page, page) /* empty */ +# define RELEASE_PAGE_LOCK(is_a_master_page, page) /* empty */ +#endif + inline static size_t real_page_size(mpage* page); inline static int page_mmu_type(mpage *page); inline static int page_mmu_protectable(mpage *page); @@ -3137,6 +3151,9 @@ void GC_init_type_tags(int count, int pair, int mutable_pair, int weakbox, int e initialized = 1; init_type_tags_worker(NULL, NULL, count, pair, mutable_pair, weakbox, ephemeron, weakarray, custbox, phantom); +#if defined(MZ_USE_PLACES) && defined(NEWGC_BTC_ACCOUNT) + init_master_btc_locks(); +#endif } else { GCPRINT(GCOUTF, "GC_init_type_tags should only be called once!\n"); abort(); @@ -3406,20 +3423,6 @@ static void mark_recur_or_push_ptr(struct NewGC *gc, void *p, int is_a_master_pa push_ptr(gc, p); } -#ifdef MZ_USE_PLACES -static void adjust_page_lock(int is_a_master_page, mpage *page, intptr_t prev, intptr_t next) -{ - if (is_a_master_page) { - while (!mzrt_cas(&page->page_lock, prev, next)) { /* spin! */ } - } -} -# define TAKE_PAGE_LOCK(is_a_master_page, page) adjust_page_lock(is_a_master_page, page, 0, 1); -# define RELEASE_PAGE_LOCK(is_a_master_page, page) adjust_page_lock(is_a_master_page, page, 1, 0); -#else -# define TAKE_PAGE_LOCK(is_a_master_page, page) /* empty */ -# define RELEASE_PAGE_LOCK(is_a_master_page, page) /* empty */ -#endif - /* This is the first mark routine. It's a bit complicated. */ void GC_mark2(const void *const_p, struct NewGC *gc) { diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index e73cbb09b3..677a8927b8 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -184,6 +184,7 @@ typedef struct NewGC { OTEntry **owner_table; unsigned int owner_table_size; AccountHook *hooks; + int master_page_btc_mark_checked; uintptr_t number_of_gc_runs; unsigned int since_last_full; From bfb4d34715d648b9f7bc272de3ccf51323ba3ae8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 16:42:23 -0600 Subject: [PATCH 118/381] fix memory accounting for useless channels Fix accounting for a channel that is without a peer for sending and/or receiving. --- racket/src/racket/gc2/mem_account.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index dee0990d92..7121add724 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -441,8 +441,10 @@ int BTC_bi_chan_mark(void *p, struct NewGC *gc) /* Race conditions here on `mem_size', and likely double counting when the same async channels are accessible from paired bi channels --- but those approximations are ok for accounting. */ - account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->sendch->mem_size), 0); - account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->recvch->mem_size), 0); + if (bc->link->sendch) + account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->sendch->mem_size), 0); + if (bc->link->recvch) + account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->recvch->mem_size), 0); } return gc->mark_table[btc_redirect_bi_chan](p, gc); } From 79738d3bf6b1e376cd3c98745399c426677cd745 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 17:27:17 -0600 Subject: [PATCH 119/381] fix no-places build --- racket/src/racket/gc2/mem_account.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 7121add724..31e6be8845 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -323,7 +323,7 @@ static void release_master_btc_mark(NewGC *gc) #else -static void check_master_btc_mark(NewGC *gc) { } +static void check_master_btc_mark(NewGC *gc, mpage *page) { } static void release_master_btc_mark(NewGC *gc) { } #endif From 152787cb0ed5e052874564d55b98b59073779de8 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Fri, 28 Aug 2015 14:49:18 -0300 Subject: [PATCH 120/381] =?UTF-8?q?JIT:=20inline=20string=3D=3F=20and=20by?= =?UTF-8?q?tes=3D=3F?= --- racket/src/racket/src/jit.h | 2 + racket/src/racket/src/jit_ts.c | 4 + racket/src/racket/src/jitcommon.c | 24 ++++ racket/src/racket/src/jitinline.c | 187 +++++++++++++++++++++++++++++- racket/src/racket/src/schpriv.h | 2 + racket/src/racket/src/string.c | 34 ++++-- 6 files changed, 240 insertions(+), 13 deletions(-) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 9f6746d79e..b6a9137ba1 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -359,6 +359,8 @@ struct scheme_jit_common_record { void *with_immed_mark_code; void *apply_to_list_tail_code, *apply_to_list_code, *apply_to_list_multi_ok_code; void *eqv_code, *eqv_branch_code; + void *bad_string_eq_2_code; + void *bad_bytes_eq_2_code; void *proc_arity_includes_code; #ifdef CAN_INLINE_ALLOC diff --git a/racket/src/racket/src/jit_ts.c b/racket/src/racket/src/jit_ts.c index 326557f752..392154a53d 100644 --- a/racket/src/racket/src/jit_ts.c +++ b/racket/src/racket/src/jit_ts.c @@ -91,6 +91,8 @@ define_ts_s_s(scheme_extflvector_length, FSRC_MARKS) define_ts_s_s(scheme_fxvector_length, FSRC_MARKS) define_ts_s_s(scheme_string_length, FSRC_MARKS) define_ts_s_s(scheme_byte_string_length, FSRC_MARKS) +define_ts_ss_s(scheme_string_eq_2, FSRC_MARKS) +define_ts_ss_s(scheme_byte_string_eq_2, FSRC_MARKS) define_ts_s_s(scheme_unbox, FSRC_MARKS) define_ts_si_s(scheme_struct_ref, FSRC_MARKS) define_ts_sis_v(scheme_struct_set, FSRC_MARKS) @@ -218,6 +220,8 @@ define_ts_s_s(scheme_box, FSRC_OTHER) # define ts_scheme_struct_ref scheme_struct_ref # define ts_scheme_struct_set scheme_struct_set # define ts_scheme_equal scheme_equal +# define ts_scheme_string_eq_2 scheme_string_eq_2 +# define ts_scheme_byte_string_eq_2 scheme_byte_string_eq_2 # define ts_extract_one_cc_mark_to_tag extract_one_cc_mark_to_tag # define ts_tail_call_with_values_from_multiple_result tail_call_with_values_from_multiple_result # define ts_raise_bad_call_with_values raise_bad_call_with_values diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index cfc53e8473..86e01617a8 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -629,6 +629,30 @@ static int common1b(mz_jit_state *jitter, void *_data) CHECK_LIMIT(); scheme_jit_register_sub_func(jitter, sjc.bad_bytes_length_code, scheme_false); + /* *** bad_string_eq_2_code *** */ + /* R0 and R1 are arguments */ + sjc.bad_string_eq_2_code = jit_get_ip(); + mz_prolog(JIT_R2); + JIT_UPDATE_THREAD_RSPTR(); + jit_prepare(2); + jit_pusharg_p(JIT_R1); + jit_pusharg_p(JIT_R0); + (void)mz_finish_lwe(ts_scheme_string_eq_2, ref); + CHECK_LIMIT(); + scheme_jit_register_sub_func(jitter, sjc.bad_string_eq_2_code, scheme_false); + + /* *** bad_bytes_eq_2_code *** */ + /* R0 and R1 are arguments */ + sjc.bad_bytes_eq_2_code = jit_get_ip(); + mz_prolog(JIT_R2); + JIT_UPDATE_THREAD_RSPTR(); + jit_prepare(2); + jit_pusharg_p(JIT_R1); + jit_pusharg_p(JIT_R0); + (void)mz_finish_lwe(ts_scheme_byte_string_eq_2, ref); + CHECK_LIMIT(); + scheme_jit_register_sub_func(jitter, sjc.bad_bytes_eq_2_code, scheme_false); + return 1; } diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index ff47e3da65..02478cadd1 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -2717,6 +2717,187 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i __END_SHORT_JUMPS__(branch_short); + return 1; + } else if (IS_NAMED_PRIM(rator, "string=?") + || IS_NAMED_PRIM(rator, "bytes=?")) { + GC_CAN_IGNORE jit_insn *ref_fx1, *ref_fx2, *ref_fail1, *ref_fail2, *ref_ucnofail; + GC_CAN_IGNORE jit_insn *ref_false1, *ref_false2 = NULL; + GC_CAN_IGNORE jit_insn *ref_true1, *ref_true2, *ref_ucfinish; + GC_CAN_IGNORE jit_insn *ref_loop; + int is_str1, is_str2, len = 0; + int string, string_type; + void * sjc_bad_code; + intptr_t string_len_val, string_val; + + if ((IS_NAMED_PRIM(rator, "string=?"))) { + string = 1; + string_type = scheme_char_string_type; + sjc_bad_code = sjc.bad_string_eq_2_code; + string_len_val = (intptr_t)&SCHEME_CHAR_STRLEN_VAL(0x0); + string_val = (intptr_t)&SCHEME_CHAR_STR_VAL(0x0); + } else if (IS_NAMED_PRIM(rator, "bytes=?")) { + string = 0; + string_type = scheme_byte_string_type; + sjc_bad_code = sjc.bad_bytes_eq_2_code; + string_len_val = (intptr_t)&SCHEME_BYTE_STRLEN_VAL(0x0); + string_val = (intptr_t)&SCHEME_BYTE_STR_VAL(0x0); + } + + is_str1 = (SAME_TYPE(SCHEME_TYPE(app->rand1), string_type)); + is_str2 = (SAME_TYPE(SCHEME_TYPE(app->rand2), string_type)); + if (string) { + if (is_str1) { + len = SCHEME_CHAR_STRLEN_VAL(app->rand1); + } else if (is_str2) { + len = SCHEME_CHAR_STRLEN_VAL(app->rand2); + } + } else { + if (is_str1) { + len = SCHEME_BYTE_STRLEN_VAL(app->rand1); + } else if (is_str2) { + len = SCHEME_BYTE_STRLEN_VAL(app->rand2); + } + } + + scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2); + CHECK_LIMIT(); + + if (need_sync) mz_rs_sync(); + + if (for_branch) { + __START_SHORT_JUMPS__(branch_short); + scheme_prepare_branch_jump(jitter, for_branch); + CHECK_LIMIT(); + __END_SHORT_JUMPS__(branch_short); + } + + __START_TINY_JUMPS__(1); + /* fail if either is not a string */ + if (!is_str1) { + ref_fx1 = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1); + jit_ldxi_s(JIT_R2, JIT_R0, &((Scheme_Object *)0x0)->type); + ref_fail1 = jit_bnei_i(jit_forward(), JIT_R2, string_type); + } + if (!is_str2) { + ref_fx2 = jit_bmsi_ul(jit_forward(), JIT_R1, 0x1); + jit_ldxi_s(JIT_V1, JIT_R1, &((Scheme_Object *)0x0)->type); + ref_fail2 = jit_bnei_i(jit_forward(), JIT_V1, string_type); + } + ref_ucnofail = jit_jmpi(jit_forward()); + CHECK_LIMIT(); + + /* fail */ + if (!is_str1) { + mz_patch_branch(ref_fx1); + mz_patch_branch(ref_fail1); + } + if (!is_str2) { + mz_patch_branch(ref_fx2); + mz_patch_branch(ref_fail2); + } + __END_TINY_JUMPS__(1); + + (void)jit_calli(sjc_bad_code); + CHECK_LIMIT(); + + /* main */ + __START_TINY_JUMPS__(1); + mz_patch_ucbranch(ref_ucnofail); + __END_TINY_JUMPS__(1); + + if (result_ignored) + return 1; + + /* false if they have different length */ + __START_TINY_OR_SHORT_JUMPS__(!for_branch, branch_short); + if (is_str1) { + jit_ldxi_l(JIT_R2, JIT_R1, string_len_val); + ref_false1 = jit_bnei_l(jit_forward(), JIT_R2, len); + } else if (is_str2) { + jit_ldxi_l(JIT_R2, JIT_R0, string_len_val); + ref_false1 = jit_bnei_l(jit_forward(), JIT_R2, len); + } else { + jit_ldxi_l(JIT_R2, JIT_R0, string_len_val); + jit_ldxi_l(JIT_V1, JIT_R1, string_len_val); + ref_false1 = jit_bner_l(jit_forward(), JIT_R2, JIT_V1); + } + __END_TINY_OR_SHORT_JUMPS__(!for_branch, branch_short); + + if ((!is_str1 && !is_str2) || len) { + __START_TINY_JUMPS__(1); + /* true if both have length zero or are eq?*/ + ref_true1 = jit_beqi_l(jit_forward(), JIT_R2, 0); + ref_true2 = jit_beqr_p(jit_forward(), JIT_R0, JIT_R1); + + /* initialize loop*/ + jit_ldxi_p(JIT_R0, JIT_R0, string_val); + jit_ldxi_p(JIT_R1, JIT_R1, string_val); + CHECK_LIMIT(); + + /* main loop*/ + if (string) { + ref_loop = jit_get_ip(); + mz_set_local_p(JIT_R0, JIT_LOCAL3); + jit_ldr_i(JIT_R0, JIT_R0); + jit_ldr_i(JIT_V1, JIT_R1); + __END_TINY_JUMPS__(1); + __START_TINY_OR_SHORT_JUMPS__(!for_branch, branch_short); + ref_false2 = jit_bner_i(jit_forward(), JIT_R0, JIT_V1); + __END_TINY_OR_SHORT_JUMPS__(!for_branch, branch_short); + __START_TINY_JUMPS__(1); + mz_get_local_p(JIT_R0, JIT_LOCAL3); + jit_addi_p(JIT_R0, JIT_R0, 1 << LOG_MZCHAR_SIZE); + jit_addi_p(JIT_R1, JIT_R1, 1 << LOG_MZCHAR_SIZE); + jit_subi_l(JIT_R2, JIT_R2, 1); + (void)jit_bnei_l(ref_loop, JIT_R2, 0); + } else { + ref_loop = jit_get_ip(); + mz_set_local_p(JIT_R0, JIT_LOCAL3); + jit_ldr_c(JIT_R0, JIT_R0); + jit_ldr_c(JIT_V1, JIT_R1); + __END_TINY_JUMPS__(1); + __START_TINY_OR_SHORT_JUMPS__(!for_branch, branch_short); + jit_extr_c_i(JIT_R0, JIT_R0); + jit_extr_c_i(JIT_V1, JIT_V1); + ref_false2 = jit_bner_i(jit_forward(), JIT_R0, JIT_V1); + __END_TINY_OR_SHORT_JUMPS__(!for_branch, branch_short); + __START_TINY_JUMPS__(1); + mz_get_local_p(JIT_R0, JIT_LOCAL3); + jit_addi_p(JIT_R0, JIT_R0, 1); + jit_addi_p(JIT_R1, JIT_R1, 1); + jit_subi_l(JIT_R2, JIT_R2, 1); + (void)jit_bnei_l(ref_loop, JIT_R2, 0); + } + CHECK_LIMIT(); + + /* true */ + mz_patch_branch(ref_true1); + mz_patch_branch(ref_true2); + __END_TINY_JUMPS__(1); + } + + if (for_branch) { + __START_SHORT_JUMPS__(branch_short); + scheme_add_branch_false(for_branch, ref_false1); + if (ref_false2) + scheme_add_branch_false(for_branch, ref_false2); + scheme_branch_for_true(jitter, for_branch); + __END_SHORT_JUMPS__(branch_short); + } else { + __START_TINY_JUMPS__(1); + jit_movi_p(dest, scheme_true); + ref_ucfinish = jit_jmpi(jit_forward()); + /* false */ + mz_patch_branch(ref_false1); + if (ref_false2) + mz_patch_branch(ref_false2); + jit_movi_p(dest, scheme_false); + /* finish */ + mz_patch_ucbranch(ref_ucfinish); + __END_TINY_JUMPS__(1); + } + CHECK_LIMIT(); + return 1; } else if (IS_NAMED_PRIM(rator, "=")) { scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 0, NULL, dest); @@ -3147,7 +3328,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else { if (unsafe) { jit_rshi_ul(JIT_R1, JIT_R1, 1); - jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_CHAR_STR_VAL((Scheme_Object *)0x0)); + jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_BYTE_STR_VAL((Scheme_Object *)0x0)); jit_ldxr_c(JIT_R0, JIT_R0, JIT_R1); jit_extr_uc_ul(JIT_R0, JIT_R0); jit_fixnum_l(dest, JIT_R0); @@ -3207,7 +3388,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } } else { if (unsafe) { - jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_CHAR_STR_VAL((Scheme_Object *)0x0)); + jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_BYTE_STR_VAL((Scheme_Object *)0x0)); jit_ldxr_c(JIT_R0, JIT_R0, JIT_V1); jit_extr_uc_ul(JIT_R0, JIT_R0); jit_fixnum_l(dest, JIT_R0); @@ -4221,7 +4402,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } } else { if (unsafe) { - jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_CHAR_STR_VAL((Scheme_Object *)0x0)); + jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_BYTE_STR_VAL((Scheme_Object *)0x0)); jit_rshi_ul(JIT_R2, JIT_R2, 1); jit_stxr_c(JIT_V1, JIT_R0, JIT_R2); if (!result_ignored) diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 8f5e2c62fb..b572e0205d 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -4121,9 +4121,11 @@ Scheme_Object *scheme_checked_set_mcdr (int argc, Scheme_Object *argv[]); Scheme_Object *scheme_checked_vector_ref(int argc, Scheme_Object **argv); Scheme_Object *scheme_checked_vector_set(int argc, Scheme_Object **argv); Scheme_Object *scheme_string_length(Scheme_Object *v); +Scheme_Object *scheme_string_eq_2(Scheme_Object *str1, Scheme_Object *str2); Scheme_Object *scheme_checked_string_ref(int argc, Scheme_Object *argv[]); Scheme_Object *scheme_checked_string_set(int argc, Scheme_Object *argv[]); Scheme_Object *scheme_byte_string_length(Scheme_Object *v); +Scheme_Object *scheme_byte_string_eq_2(Scheme_Object *str1, Scheme_Object *str2); Scheme_Object *scheme_checked_byte_string_ref(int argc, Scheme_Object *argv[]); Scheme_Object *scheme_checked_byte_string_set(int argc, Scheme_Object *argv[]); Scheme_Object *scheme_checked_syntax_e(int argc, Scheme_Object **argv); diff --git a/racket/src/racket/src/string.c b/racket/src/racket/src/string.c index f794a5d324..4d31ff0a30 100644 --- a/racket/src/racket/src/string.c +++ b/racket/src/racket/src/string.c @@ -510,11 +510,10 @@ scheme_init_string (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_NARY_INLINED); scheme_add_global_constant("string-set!", p, env); - scheme_add_global_constant("string=?", - scheme_make_immed_prim(string_eq, - "string=?", - 2, -1), - env); + p = scheme_make_immed_prim(string_eq, "string=?", 2, -1); + SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_BINARY_INLINED); + scheme_add_global_constant("string=?", p, env); + scheme_add_global_constant("string-locale=?", scheme_make_immed_prim(string_locale_eq, "string-locale=?", @@ -788,11 +787,10 @@ scheme_init_string (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_NARY_INLINED); scheme_add_global_constant("bytes-set!", p, env); - scheme_add_global_constant("bytes=?", - scheme_make_immed_prim(byte_string_eq, - "bytes=?", - 2, -1), - env); + p = scheme_make_immed_prim(byte_string_eq, "bytes=?", 2, -1); + SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_BINARY_INLINED); + scheme_add_global_constant("bytes=?", p, env); + scheme_add_global_constant("bytes?", mz_char_strcmp_ci, >, 1, 0) +Scheme_Object *scheme_string_eq_2(Scheme_Object *str1, Scheme_Object *str2) +{ + Scheme_Object *a[2]; + a[0] = str1; + a[1] = str2; + return string_eq(2, a); +} + /**********************************************************************/ /* byte strings */ /**********************************************************************/ @@ -1268,6 +1274,14 @@ GEN_BYTE_STRING_COMP(byte_string_gt, "bytes>?", mz_strcmp, >) GEN_BYTE_STRING_PATH_COMP(path_lt, "path char string */ /**********************************************************************/ From ab6b58a4769955566fb217333a46f06cf1c186fb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 20:21:29 -0600 Subject: [PATCH 121/381] avoid compiler warning --- racket/src/racket/src/jitinline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 02478cadd1..509371925a 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -2735,7 +2735,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i sjc_bad_code = sjc.bad_string_eq_2_code; string_len_val = (intptr_t)&SCHEME_CHAR_STRLEN_VAL(0x0); string_val = (intptr_t)&SCHEME_CHAR_STR_VAL(0x0); - } else if (IS_NAMED_PRIM(rator, "bytes=?")) { + } else { /* IS_NAMED_PRIM(rator, "bytes=?") */ string = 0; string_type = scheme_byte_string_type; sjc_bad_code = sjc.bad_bytes_eq_2_code; From 94e5b1723b207cd4a79136c05113041a7eec9413 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 28 Aug 2015 20:24:46 -0600 Subject: [PATCH 122/381] JIT simplification Remove unused and confusing attempt to avoid runstack sync. --- racket/src/racket/src/jit.c | 86 +++------------------------ racket/src/racket/src/jit.h | 6 +- racket/src/racket/src/jitinline.c | 96 +++++++++++++++---------------- 3 files changed, 59 insertions(+), 129 deletions(-) diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 4fbfd74ef3..4fd13aff1e 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -434,68 +434,6 @@ static int is_short(Scheme_Object *obj, int fuel) } #endif -static int no_sync_change(Scheme_Object *obj, int fuel) -{ - Scheme_Type t; - - if (fuel <= 0) - return fuel; - - t = SCHEME_TYPE(obj); - - switch (t) { - case scheme_application2_type: - { - Scheme_App2_Rec *app = (Scheme_App2_Rec *)obj; - if (SCHEME_PRIMP(app->rator) - && (SCHEME_PRIM_PROC_OPT_FLAGS(app->rator) & SCHEME_PRIM_IS_UNARY_INLINED) - && (IS_NAMED_PRIM(app->rator, "car") - || IS_NAMED_PRIM(app->rator, "cdr") - || IS_NAMED_PRIM(app->rator, "cadr") - || IS_NAMED_PRIM(app->rator, "cdar") - || IS_NAMED_PRIM(app->rator, "caar") - || IS_NAMED_PRIM(app->rator, "cddr"))) { - return no_sync_change(app->rand, fuel - 1); - } - return 0; - } - break; - case scheme_sequence_type: - { - Scheme_Sequence *seq = (Scheme_Sequence *)obj; - int i; - - fuel -= seq->count; - for (i = seq->count; i--; ) { - fuel = no_sync_change(seq->array[i], fuel); - } - return fuel; - } - break; - case scheme_branch_type: - { - Scheme_Branch_Rec *branch = (Scheme_Branch_Rec *)obj; - fuel -= 3; - fuel = no_sync_change(branch->test, fuel); - fuel = no_sync_change(branch->tbranch, fuel); - return no_sync_change(branch->fbranch, fuel); - } - case scheme_local_type: - if (JIT_TYPE_NEEDS_BOXING(SCHEME_GET_LOCAL_TYPE(obj))) - return 0; - else - return fuel - 1; - case scheme_toplevel_type: - case scheme_local_unbox_type: - return fuel - 1; - default: - if (t > _scheme_values_types_) - return fuel - 1; - else - return 0; - } -} - Scheme_Object *scheme_extract_global(Scheme_Object *o, Scheme_Native_Closure *nc, int local_only) { /* GLOBAL ASSUMPTION: we assume that globals are the last thing @@ -1677,7 +1615,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail mz_jit_unbox_state ubs; int ubd, save_ubd; int pushed_marks; - int nsrs, nsrs1, g1, g2, amt, need_sync, flostack, flostack_pos; + int nsrs, nsrs1, g1, g2, amt, flostack, flostack_pos; int else_is_empty = 0, i, can_chain_branch, chain_true, chain_false, old_self_pos; #ifdef NEED_LONG_BRANCHES int then_short_ok, else_short_ok; @@ -1728,14 +1666,6 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail LOG_IT(("if...\n")); - /* Avoid rs_sync if neither branch changes the sync state? - Currently, we force a sync, anyway. */ - if ((no_sync_change(branch->tbranch, 32) > 0) - && (no_sync_change(branch->fbranch, 32) > 0)) - need_sync = 0; - else - need_sync = 1; - if (result_ignored && (SCHEME_TYPE(branch->fbranch) > _scheme_compiled_values_types_)) else_is_empty = 1; @@ -1746,7 +1676,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail scheme_mz_unbox_save(jitter, &ubs); - if (!scheme_generate_inlined_test(jitter, branch->test, then_short_ok, &for_this_branch, need_sync)) { + if (!scheme_generate_inlined_test(jitter, branch->test, then_short_ok, &for_this_branch)) { CHECK_LIMIT(); generate_non_tail_with_branch_and_values(branch->test, jitter, 0, 1, 0, &for_this_branch, NULL); CHECK_LIMIT(); @@ -1802,7 +1732,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail if (!is_tail) { if (amt) mz_rs_inc(amt); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); } __START_SHORT_JUMPS__(else_short_ok); if (else_is_empty) @@ -1821,7 +1751,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail } jitter->need_set_rs = nsrs; jitter->pushed_marks = pushed_marks; - if (need_sync) mz_rs_sync_0(); + mz_rs_sync_0(); if (old_self_pos != jitter->self_pos) scheme_signal_error("internal error: self position moved across branch"); @@ -1871,7 +1801,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail if (!is_tail) { if (amt) mz_rs_inc(amt); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); } } else if (g2 == 2) { jitter->need_set_rs = 0; @@ -1999,7 +1929,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w if (for_branch) { mz_rs_sync(); - if (scheme_generate_inlined_test(jitter, obj, for_branch->branch_short, for_branch, 1)) + if (scheme_generate_inlined_test(jitter, obj, for_branch->branch_short, for_branch)) return 1; CHECK_LIMIT(); } @@ -2654,7 +2584,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w Scheme_Object *args[2]; int r; - r = scheme_generate_inlined_unary(jitter, app, is_tail, multi_ok, NULL, 1, 0, result_ignored, target); + r = scheme_generate_inlined_unary(jitter, app, is_tail, multi_ok, NULL, 0, result_ignored, target); CHECK_LIMIT(); if (r) { if (for_branch) finish_branch(jitter, target, for_branch); @@ -2704,7 +2634,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w return 1; } - r = scheme_generate_inlined_binary(jitter, app, is_tail, multi_ok, NULL, 1, 0, result_ignored, target); + r = scheme_generate_inlined_binary(jitter, app, is_tail, multi_ok, NULL, 0, result_ignored, target); CHECK_LIMIT(); if (r) { if (for_branch) finish_branch(jitter, target, for_branch); diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index b6a9137ba1..f921be2fd5 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -1404,16 +1404,16 @@ int scheme_inlined_unary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_stat int scheme_inlined_binary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter); int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter); int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, int is_tail, int multi_ok, - Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored, + Branch_Info *for_branch, int branch_short, int result_ignored, int dest); int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, int is_tail, int multi_ok, - Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored, + Branch_Info *for_branch, int branch_short, int result_ignored, int dest); int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int is_tail, int multi_ok, Branch_Info *for_branch, int branch_short, int result_ignored, int dest); int scheme_generate_inlined_test(mz_jit_state *jitter, Scheme_Object *obj, int branch_short, - Branch_Info *for_branch, int need_sync); + Branch_Info *for_branch); int scheme_generate_cons_alloc(mz_jit_state *jitter, int rev, int inline_retry, int known_list, int dest); int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, int inline_slow, int pop_and_jump, diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 509371925a..f42b64583a 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -213,7 +213,7 @@ int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec *app, Scheme_Object *cnst, Scheme_Object *cnst2, - Branch_Info *for_branch, int branch_short, int need_sync, + Branch_Info *for_branch, int branch_short, int dest) /* de-sync'd ok */ { @@ -228,7 +228,7 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec mz_runstack_unskipped(jitter, 1); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); __START_SHORT_JUMPS__(branch_short); @@ -264,7 +264,7 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app, Scheme_Type lo_ty, Scheme_Type hi_ty, int can_chaperone, - Branch_Info *for_branch, int branch_short, int need_sync, + Branch_Info *for_branch, int branch_short, int dest) { GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *ref5; @@ -281,7 +281,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app mz_runstack_unskipped(jitter, 1); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); __START_SHORT_JUMPS__(branch_short); @@ -879,7 +879,7 @@ static int is_cXr_prim(const char *name) } static int generate_inlined_constant_varref_test(mz_jit_state *jitter, Scheme_Object *obj, - Branch_Info *for_branch, int branch_short, int need_sync, + Branch_Info *for_branch, int branch_short, int dest) { GC_CAN_IGNORE jit_insn *ref1, *ref2; @@ -904,7 +904,7 @@ static int generate_inlined_constant_varref_test(mz_jit_state *jitter, Scheme_Ob mz_runstack_unskipped(jitter, 1); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); __START_SHORT_JUMPS__(branch_short); @@ -941,7 +941,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, int dest); int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, int is_tail, int multi_ok, - Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored, + Branch_Info *for_branch, int branch_short, int result_ignored, int dest) /* de-sync's, unless branch */ { @@ -969,7 +969,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in if (SAME_OBJ(rator, scheme_varref_const_p_proc) && SAME_TYPE(SCHEME_TYPE(app->rand), scheme_varref_form_type)) { - generate_inlined_constant_varref_test(jitter, app->rand, for_branch, branch_short, need_sync, dest); + generate_inlined_constant_varref_test(jitter, app->rand, for_branch, branch_short, dest); return 1; } @@ -982,85 +982,85 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in scheme_direct_call_count++; if (IS_NAMED_PRIM(rator, "not")) { - generate_inlined_constant_test(jitter, app, scheme_false, NULL, for_branch, branch_short, need_sync, dest); + generate_inlined_constant_test(jitter, app, scheme_false, NULL, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "null?")) { - generate_inlined_constant_test(jitter, app, scheme_null, NULL, for_branch, branch_short, need_sync, dest); + generate_inlined_constant_test(jitter, app, scheme_null, NULL, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "void?")) { - generate_inlined_constant_test(jitter, app, scheme_void, NULL, for_branch, branch_short, need_sync, dest); + generate_inlined_constant_test(jitter, app, scheme_void, NULL, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "pair?")) { - generate_inlined_type_test(jitter, app, scheme_pair_type, scheme_pair_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_pair_type, scheme_pair_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "mpair?")) { - generate_inlined_type_test(jitter, app, scheme_mutable_pair_type, scheme_mutable_pair_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_mutable_pair_type, scheme_mutable_pair_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "symbol?")) { - generate_inlined_type_test(jitter, app, scheme_symbol_type, scheme_symbol_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_symbol_type, scheme_symbol_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "keyword?")) { - generate_inlined_type_test(jitter, app, scheme_keyword_type, scheme_keyword_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_keyword_type, scheme_keyword_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "syntax?")) { - generate_inlined_type_test(jitter, app, scheme_stx_type, scheme_stx_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_stx_type, scheme_stx_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "char?")) { - generate_inlined_type_test(jitter, app, scheme_char_type, scheme_char_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_char_type, scheme_char_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "boolean?")) { - generate_inlined_constant_test(jitter, app, scheme_false, scheme_true, for_branch, branch_short, need_sync, dest); + generate_inlined_constant_test(jitter, app, scheme_false, scheme_true, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "number?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_complex_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_complex_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "real?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_double_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_double_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "exact-integer?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_bignum_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_bignum_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fixnum?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_integer_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_integer_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "inexact-real?")) { - generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, scheme_double_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, scheme_double_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flonum?")) { - generate_inlined_type_test(jitter, app, scheme_double_type, scheme_double_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_double_type, scheme_double_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "extflonum?")) { - generate_inlined_type_test(jitter, app, scheme_long_double_type, scheme_long_double_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_long_double_type, scheme_long_double_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "single-flonum?")) { - generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, SCHEME_FLOAT_TYPE, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, SCHEME_FLOAT_TYPE, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "procedure?")) { - generate_inlined_type_test(jitter, app, scheme_prim_type, scheme_proc_chaperone_type, 1, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_prim_type, scheme_proc_chaperone_type, 1, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "chaperone?")) { - generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, -1, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, -1, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "impersonator?")) { - generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "vector?")) { - generate_inlined_type_test(jitter, app, scheme_vector_type, scheme_vector_type, 1, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_vector_type, scheme_vector_type, 1, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "box?")) { - generate_inlined_type_test(jitter, app, scheme_box_type, scheme_box_type, 1, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_box_type, scheme_box_type, 1, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "string?")) { - generate_inlined_type_test(jitter, app, scheme_char_string_type, scheme_char_string_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_char_string_type, scheme_char_string_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "bytes?")) { - generate_inlined_type_test(jitter, app, scheme_byte_string_type, scheme_byte_string_type, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_byte_string_type, scheme_byte_string_type, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "path?")) { - generate_inlined_type_test(jitter, app, SCHEME_PLATFORM_PATH_KIND, SCHEME_PLATFORM_PATH_KIND, 0, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, SCHEME_PLATFORM_PATH_KIND, SCHEME_PLATFORM_PATH_KIND, 0, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "eof-object?")) { - generate_inlined_constant_test(jitter, app, scheme_eof, NULL, for_branch, branch_short, need_sync, dest); + generate_inlined_constant_test(jitter, app, scheme_eof, NULL, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "zero?")) { scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 0, NULL, dest); @@ -1087,7 +1087,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); __START_SHORT_JUMPS__(branch_short); @@ -1154,7 +1154,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); if (for_branch) { scheme_prepare_branch_jump(jitter, for_branch); @@ -2010,10 +2010,10 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in return 1; } else if (IS_NAMED_PRIM(rator, "future?")) { - generate_inlined_type_test(jitter, app, scheme_future_type, scheme_future_type, 1, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_future_type, scheme_future_type, 1, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fsemaphore?")) { - generate_inlined_type_test(jitter, app, scheme_fsemaphore_type, scheme_fsemaphore_type, 1, for_branch, branch_short, need_sync, dest); + generate_inlined_type_test(jitter, app, scheme_fsemaphore_type, scheme_fsemaphore_type, 1, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "future") || IS_NAMED_PRIM(rator, "touch") @@ -2473,7 +2473,7 @@ static int allocate_rectangular(mz_jit_state *jitter, int dest) } int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, int is_tail, int multi_ok, - Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored, + Branch_Info *for_branch, int branch_short, int result_ignored, int dest) /* de-sync's; for branch, sync'd before */ { @@ -2481,7 +2481,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i if (SCHEME_PRIMP(rator) && IS_NAMED_PRIM(rator, "ptr-ref")) { Scheme_App_Rec *app2; - if (need_sync) mz_rs_sync(); + mz_rs_sync(); app2 = scheme_malloc_application(3); app2->args[0] = app->rator; app2->args[1] = app->rand1; @@ -2532,7 +2532,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_generate_non_tail(a2, jitter, 0, 1, 0); CHECK_LIMIT(); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); mz_runstack_unskipped(jitter, 2); @@ -2579,7 +2579,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_generate_two_args(a2, a1, jitter, 0, 2); CHECK_LIMIT(); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); __START_SHORT_JUMPS__(branch_short); @@ -2654,7 +2654,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_generate_two_args(app->rand1, app->rand2, jitter, 0, 2); CHECK_LIMIT(); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); __START_SHORT_JUMPS__(branch_short); @@ -2762,7 +2762,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2); CHECK_LIMIT(); - if (need_sync) mz_rs_sync(); + mz_rs_sync(); if (for_branch) { __START_SHORT_JUMPS__(branch_short); @@ -5062,16 +5062,16 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, } int scheme_generate_inlined_test(mz_jit_state *jitter, Scheme_Object *obj, int branch_short, - Branch_Info *for_branch, int need_sync) + Branch_Info *for_branch) /* de-sync'd ok; syncs before jump */ { switch (SCHEME_TYPE(obj)) { case scheme_application_type: return scheme_generate_inlined_nary(jitter, (Scheme_App_Rec *)obj, 0, 0, for_branch, branch_short, 0, JIT_R0); case scheme_application2_type: - return scheme_generate_inlined_unary(jitter, (Scheme_App2_Rec *)obj, 0, 0, for_branch, branch_short, need_sync, 0, JIT_R0); + return scheme_generate_inlined_unary(jitter, (Scheme_App2_Rec *)obj, 0, 0, for_branch, branch_short, 0, JIT_R0); case scheme_application3_type: - return scheme_generate_inlined_binary(jitter, (Scheme_App3_Rec *)obj, 0, 0, for_branch, branch_short, need_sync, 0, JIT_R0); + return scheme_generate_inlined_binary(jitter, (Scheme_App3_Rec *)obj, 0, 0, for_branch, branch_short, 0, JIT_R0); } return 0; From 6beff43439752b2a1ea61c1f90670ab43971211c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 29 Aug 2015 11:44:33 -0600 Subject: [PATCH 123/381] fix `expand[-syntax[-to-top-form]]` to add namespace's scope Make `expand` more consistent with `eval` and with the old expander. --- pkgs/racket-test-core/tests/racket/macro.rktl | 20 +++++++++++++++++++ racket/src/racket/src/eval.c | 10 ++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/macro.rktl b/pkgs/racket-test-core/tests/racket/macro.rktl index 669056f3e1..6f6192b9ce 100644 --- a/pkgs/racket-test-core/tests/racket/macro.rktl +++ b/pkgs/racket-test-core/tests/racket/macro.rktl @@ -1335,6 +1335,26 @@ #'#t)]) (void (m))) +;; ---------------------------------------- +;; Check that `expand-syntax` attaches the namespace's + +(test 573 + 'expand + (parameterize ([current-namespace (make-base-namespace)]) + (eval '(require (for-syntax racket/base))) + (eval '(define-syntax (m stx) + (with-syntax ([id (datum->syntax #f 'gen-id)]) + #`(begin + (define id 573) + id)))) + (define stx (namespace-syntax-introduce (datum->syntax #f '(m)))) + (syntax-case (expand-syntax-to-top-form stx) (begin) + [(begin a b) + (begin + (eval-syntax #'a) + (eval-syntax (expand-syntax #'b)))]))) + + ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 01cf3f8cee..5fed396a50 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -4620,6 +4620,12 @@ static void *expand_k(void) obj = scheme_top_introduce(obj, env->genv); } + if (rename && env->genv->stx_context) { + obj = scheme_stx_push_introduce_module_context(obj, env->genv->stx_context); + env->expand_result_adjust = scheme_stx_push_introduce_module_context; + env->expand_result_adjust_arg = env->genv->stx_context; + } + observer = scheme_get_expand_observe(); SCHEME_EXPAND_OBSERVE_START_EXPAND(observer); @@ -4694,10 +4700,6 @@ static void *expand_k(void) break; } - if (rename && !just_to_top) { - /* scheme_simplify_stx(obj, scheme_new_stx_simplify_cache()); */ /* too expensive */ - } - return obj; } From 0e4d9a68afa204e8d887842a663efe28e694fe1c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 29 Aug 2015 20:12:27 -0600 Subject: [PATCH 124/381] fix executable creation for cross-installation --- pkgs/racket-doc/scribblings/raco/exe-api.scrbl | 14 +++++++++++--- racket/collects/compiler/embed.rkt | 2 +- racket/collects/compiler/find-exe.rkt | 13 ++++++++++--- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl index 3c908dc7b9..f469bdd625 100644 --- a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl @@ -473,9 +473,17 @@ A unit that imports nothing and exports @racket[compiler:embed^].} @defmodule[compiler/find-exe] -@defproc[(find-exe [gracket? any/c #f] - [variant (or/c 'cgc '3m) (system-type 'gc)]) +@defproc[(find-exe [#:cross? cross? any/c #f] + [gracket? any/c #f] + [variant (or/c 'cgc '3m) (if cross? + (cross-system-type 'gc) + (system-type 'gc))]) path?]{ Finds the path to the @exec{racket} or @exec{gracket} (when - @racket[gracket?] is true) executable.} + @racket[gracket?] is true) executable. + + If @racket[cross?] is true, the executable is found for the target + platform in @seclink["cross-system"]{cross-installation mode}. + + @history[#:changed "6.2.900.11" @elem{Added the @racket[#:cross?] argument.}]} diff --git a/racket/collects/compiler/embed.rkt b/racket/collects/compiler/embed.rkt index 105b4966eb..f95d115feb 100644 --- a/racket/collects/compiler/embed.rkt +++ b/racket/collects/compiler/embed.rkt @@ -1413,7 +1413,7 @@ cmdline)) . < . 80)) (error 'create-embedding-executable "command line too long: ~e" cmdline)) (check-collects-path 'create-embedding-executable collects-path collects-path-bytes) - (let ([exe (find-exe mred? variant)]) + (let ([exe (find-exe #:cross? #t mred? variant)]) (when verbose? (eprintf "Copying to ~s\n" dest)) (let-values ([(dest-exe orig-exe osx?) diff --git a/racket/collects/compiler/find-exe.rkt b/racket/collects/compiler/find-exe.rkt index 616a6c3d07..1dfc67cf54 100644 --- a/racket/collects/compiler/find-exe.rkt +++ b/racket/collects/compiler/find-exe.rkt @@ -1,9 +1,14 @@ #lang racket/base (require setup/dirs - setup/variant) + setup/variant + setup/cross-system) (provide find-exe) -(define (find-exe [mred? #f] [variant (system-type 'gc)]) +(define (find-exe #:cross? [cross? #f] + [mred? #f] + [variant (if cross? + (cross-system-type 'gc) + (system-type 'gc))]) (let* ([base (if mred? (find-lib-dir) (find-console-bin-dir))] @@ -15,7 +20,9 @@ variant))]) (let ([exe (build-path base - (case (system-type) + (case (if cross? + (cross-system-type) + (system-type)) [(macosx) (cond [(not mred?) From ad4dcdeac0a4e025dd81c6a60a553bf56ae03943 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 29 Aug 2015 18:46:58 -0600 Subject: [PATCH 125/381] cross-compilation support in the top-level makefile --- INSTALL.txt | 15 ++++-- Makefile | 55 +++++++++++---------- racket/collects/setup/unixstyle-install.rkt | 8 +-- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/INSTALL.txt b/INSTALL.txt index 202705e4ba..5b96efcad5 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -183,10 +183,17 @@ but under Windows, encoding-conversion, extflonum, and SSL functionality is hobbled until native libraries from the `racket-win32-i386' or `racket-win32-x86_64' package are installed. -On all platforms, `JOB_OPTIONS' as a makefile variable and -`PLT_SETUP_OPTIONS' as an environment variable are passed on to the -`raco setup' that is used to build minimal-Racket libraries. See the -documentation for `raco setup' for information on the options. +On all platforms, fom the top-level makefile, `JOB_OPTIONS' as a +makefile variable and `PLT_SETUP_OPTIONS' as an environment variable +are passed on to the `raco setup' that is used to build minimal-Racket +libraries. See the documentation for `raco setup' for information on +the options. + +For cross compilation, add configuration options to +`CONFIGURE_ARGS_qq="..."' as descibed in the "README" of "racket/src", +but also add a `PLAIN_RACKET=...' argument for the top-level makefile +to specify the same executable as in an `--enable-racket=...' for +`configure'. Installing Packages ------------------- diff --git a/Makefile b/Makefile index 3d354ec30a..842eb0ba36 100644 --- a/Makefile +++ b/Makefile @@ -29,14 +29,15 @@ PKGS = main-distribution main-distribution-test PLAIN_RACKET = racket/bin/racket WIN32_PLAIN_RACKET = racket\racket -PLAIN_RACO = racket/bin/racket -N raco -l- raco -WIN32_PLAIN_RACO = racket\racket -N raco -l- raco +# In case of cross-installation, point explicitly to local content: +RUN_RACKET = $(PLAIN_RACKET) -G racket/etc -X racket/collects +WIN32_RUN_RACKET = $(WIN32_PLAIN_RACKET) -G racket/etc -X racket/collects + +RUN_RACO = $(RUN_RACKET) -N raco -l- raco +WIN32_RUN_RACO = $(WIN32_RUN_RACKET) -N raco -l- raco DEFAULT_SRC_CATALOG = http://pkgs.racket-lang.org -MACOSX_CHECK_ARGS = -I racket/base -e '(case (system-type) [(macosx) (exit 0)] [else (exit 1)])' -MACOSX_CHECK = $(PLAIN_RACKET) -G build/config $(MACOSX_CHECK_ARGS) - CPUS = in-place: @@ -61,18 +62,18 @@ ALL_PLT_SETUP_OPTIONS = $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS) plain-in-place: $(MAKE) base $(MAKE) pkgs-catalog - $(PLAIN_RACO) pkg update $(UPDATE_PKGS_ARGS) - $(PLAIN_RACO) pkg install $(INSTALL_PKGS_ARGS) - $(PLAIN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS) - $(PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) + $(RUN_RACO) pkg update $(UPDATE_PKGS_ARGS) + $(RUN_RACO) pkg install $(INSTALL_PKGS_ARGS) + $(RUN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS) + $(RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) win32-in-place: $(MAKE) win32-base $(MAKE) win32-pkgs-catalog - $(WIN32_PLAIN_RACO) pkg update $(UPDATE_PKGS_ARGS) - $(WIN32_PLAIN_RACO) pkg install $(INSTALL_PKGS_ARGS) - $(WIN32_PLAIN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS) - $(WIN32_PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) + $(WIN32_RUN_RACO) pkg update $(UPDATE_PKGS_ARGS) + $(WIN32_RUN_RACO) pkg install $(INSTALL_PKGS_ARGS) + $(WIN32_RUN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS) + $(WIN32_RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) # Rebuild without consulting catalogs or package sources: @@ -86,11 +87,11 @@ cpus-as-is: plain-as-is: $(MAKE) base - $(PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) + $(RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) win32-as-is: $(MAKE) win32-base - $(WIN32_PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) + $(WIN32_RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS) # ------------------------------------------------------------ # Unix-style build (Unix and Mac OS X, only) @@ -299,11 +300,11 @@ SVR_PRT = $(SERVER):$(SERVER_PORT) SVR_CAT = http://$(SVR_PRT)/$(SERVER_CATALOG_PATH) # Helper macros: -USER_CONFIG = -G build/user/config -A build/user -RACKET = racket/bin/racket $(USER_CONFIG) -RACO = racket/bin/racket $(USER_CONFIG) -N raco -l- raco -WIN32_RACKET = racket\racket $(USER_CONFIG) -WIN32_RACO = racket\racket $(USER_CONFIG) -N raco -l- raco +USER_CONFIG = -G build/user/config -X racket/collects -A build/user +RACKET = $(PLAIN_RACKET) $(USER_CONFIG) +RACO = $(PLAIN_RACKET) $(USER_CONFIG) -N raco -l- raco +WIN32_RACKET = $(WIN32_PLAIN_RACKET) $(USER_CONFIG) +WIN32_RACO = $(WIN32_PLAIN_RACKET) $(USER_CONFIG) -N raco -l- raco X_AUTO_OPTIONS = --skip-installed --deps search-auto --pkgs $(JOB_OPTIONS) USER_AUTO_OPTIONS = --scope user $(X_AUTO_OPTIONS) LOCAL_USER_AUTO = --catalog build/local/catalog $(USER_AUTO_OPTIONS) @@ -312,9 +313,9 @@ REMOTE_USER_AUTO = --catalog $(SVR_CAT) $(USER_AUTO_OPTIONS) REMOTE_INST_AUTO = --catalog $(SVR_CAT) --scope installation $(X_AUTO_OPTIONS) CONFIG_MODE_q = "$(CONFIG)" "$(CONFIG_MODE)" BUNDLE_CONFIG = bundle/racket/etc/config.rktd -BUNDLE_RACO_FLAGS = -A bundle/user -l raco -BUNDLE_RACO = bundle/racket/bin/racket $(BUNDLE_RACO_FLAGS) -WIN32_BUNDLE_RACO = bundle\racket\racket $(BUNDLE_RACO_FLAGS) +BUNDLE_RACO_FLAGS = -G bundle/racket/config -X bundle/racket/collects -A bundle/user -l raco +BUNDLE_RACO = $(PLAIN_RACKET) $(BUNDLE_RACO_FLAGS) +WIN32_BUNDLE_RACO = $(WIN32_PLAIN_RACKET) $(BUNDLE_RACO_FLAGS) # ------------------------------------------------------------ # Linking all packages (development mode; not an installer build) @@ -323,9 +324,9 @@ PKGS_CATALOG = -U -G build/config -l- pkg/dirs-catalog --link --check-metadata PKGS_CONFIG = -U -G build/config racket/src/pkgs-config.rkt pkgs-catalog: - $(PLAIN_RACKET) $(PKGS_CATALOG) racket/share/pkgs-catalog pkgs - $(PLAIN_RACKET) $(PKGS_CONFIG) "$(DEFAULT_SRC_CATALOG)" "$(SRC_CATALOG)" - $(PLAIN_RACKET) racket/src/pkgs-check.rkt racket/share/pkgs-catalog + $(RUN_RACKET) $(PKGS_CATALOG) racket/share/pkgs-catalog pkgs + $(RUN_RACKET) $(PKGS_CONFIG) "$(DEFAULT_SRC_CATALOG)" "$(SRC_CATALOG)" + $(RUN_RACKET) racket/src/pkgs-check.rkt racket/share/pkgs-catalog win32-pkgs-catalog: $(MAKE) pkgs-catalog PLAIN_RACKET="$(WIN32_PLAIN_RACKET)" @@ -428,7 +429,7 @@ binary-catalog-server: # client is the same as the server. PROP_ARGS = SERVER=$(SERVER) SERVER_PORT=$(SERVER_PORT) SERVER_HOSTS="$(SERVER_HOSTS)" \ - PKGS="$(PKGS)" BUILD_STAMP="$(BUILD_STAMP)" \ + PKGS="$(PKGS)" PLAIN_RACKET="$(PLAIN_RACKET)" BUILD_STAMP="$(BUILD_STAMP)" \ RELEASE_MODE=$(RELEASE_MODE) SOURCE_MODE=$(SOURCE_MODE) \ VERSIONLESS_MODE=$(VERSIONLESS_MODE) MAC_PKG_MODE=$(MAC_PKG_MODE) \ PKG_SOURCE_MODE="$(PKG_SOURCE_MODE)" INSTALL_NAME="$(INSTALL_NAME)"\ diff --git a/racket/collects/setup/unixstyle-install.rkt b/racket/collects/setup/unixstyle-install.rkt index bcc6e3ff56..5a94021a42 100644 --- a/racket/collects/setup/unixstyle-install.rkt +++ b/racket/collects/setup/unixstyle-install.rkt @@ -28,6 +28,7 @@ ;; path names. #lang racket/base +(require setup/cross-system) (module test racket/base) @@ -377,7 +378,7 @@ (printf ";; generated by unixstyle-install\n") (printf "#hash(\n") (out! 'doc-dir (dir: 'doc)) - (when (eq? 'shared (system-type 'link)) ; never true for now + (when (eq? 'shared (cross-system-type 'link)) ; never true for now (out! 'dll-dir (dir: 'lib))) (out! 'lib-dir (dir: 'librkt)) (out! 'share-dir (dir: 'sharerkt)) @@ -466,7 +467,7 @@ (error "Cannot handle distribution of shared-libraries (yet)")) (with-handlers ([exn? (lambda (e) (undo-changes) (raise e))]) (define binfiles (ls* "bin")) - (if (eq? 'windows (system-type)) + (if (eq? 'windows (cross-system-type)) ;; Windows executables appear in the immediate directory: (for ([f (in-list (directory-list))]) (when (and (file-exists? f) @@ -483,7 +484,8 @@ (parameterize ([current-skip-filter (make-apps-skip)]) (do-tree "share" 'sharerkt)) (do-tree "etc" 'config) - (do-tree "man" 'man #:missing 'skip) ; not included for Windows + (unless (eq? 'windows (cross-system-type)) + (do-tree "man" 'man #:missing 'skip)) ;; (when (and (not (equal? (dir: 'src) "")) (directory-exists? "src")) ;; (do-tree "src" 'src)) ;; don't use the above -- it would be pointless to put the source tree in From 1b778bf34b97e628d3ea557a1a564d1a23d692e1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 30 Aug 2015 07:01:10 -0600 Subject: [PATCH 126/381] fix GRacket paths for MinGW build --- racket/src/configure | 9 +++++++++ racket/src/gracket/Makefile.in | 4 ++-- racket/src/racket/configure.ac | 7 +++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/racket/src/configure b/racket/src/configure index 31475b26c4..152d29f6d1 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -637,7 +637,9 @@ CGC MMM_CAP_INSTALLED MMM_INSTALLED MMM +GUI_CONFIG_PATH CONFIG_PATH +GUI_COLLECTS_PATH COLLECTS_PATH includepltdir etcpltdir @@ -2970,6 +2972,9 @@ else INSTALL_ORIG_TREE=no fi +GUI_COLLECTS_PATH="${COLLECTS_PATH}" +GUI_CONFIG_PATH="${CONFIG_PATH}" + ###### Make sure GRacket is really there ###### if test "${enable_gracket}" = "yes" ; then @@ -4635,7 +4640,9 @@ case "$host_os" in MZINSTALLBINDIR="${MZINSTALLBINDIR}/.." EXE_SUFFIX=".exe" COLLECTS_PATH="collects" + GUI_COLLECTS_PATH="../collects" CONFIG_PATH="etc" + GUI_CONFIG_PATH="../etc" skip_iconv_check=yes check_for_mprotect=no @@ -6836,6 +6843,8 @@ LIBS="$LIBS $EXTRALIBS" + + diff --git a/racket/src/gracket/Makefile.in b/racket/src/gracket/Makefile.in index 2e6ce4e061..7bdf0793b8 100644 --- a/racket/src/gracket/Makefile.in +++ b/racket/src/gracket/Makefile.in @@ -209,7 +209,7 @@ install-wx_xt-cgc: $(MAKE) @MRLIBINSTALL@-cgc-wx_xt cd ..; $(ICP) gracket/gracket@CGC@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@" cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@" - @RUN_RACKET_CGC@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ + @RUN_RACKET_CGC@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @GUI_COLLECTS_PATH@ @GUI_CONFIG_PATH@ install-wx_xt-cgc-final: $(NOOP) @@ -224,7 +224,7 @@ install-wx_xt-3m: $(MAKE) @MRLIBINSTALL@-3m-wx_xt cd ..; $(ICP) gracket/gracket@MMM@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@" - @RUN_RACKET_MMM@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @COLLECTS_PATH@ @CONFIG_PATH@ + @RUN_RACKET_MMM@ $(SELF_RACKET_FLAGS) -cu "$(srcdir)/../racket/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @GUI_COLLECTS_PATH@ @GUI_CONFIG_PATH@ install-wx_xt-3m-final: $(NOOP) diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 71ce6cdfe7..9d0e0d5a39 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -248,6 +248,9 @@ else INSTALL_ORIG_TREE=no fi +GUI_COLLECTS_PATH="${COLLECTS_PATH}" +GUI_CONFIG_PATH="${CONFIG_PATH}" + ###### Make sure GRacket is really there ###### if test "${enable_gracket}" = "yes" ; then @@ -766,7 +769,9 @@ case "$host_os" in MZINSTALLBINDIR="${MZINSTALLBINDIR}/.." EXE_SUFFIX=".exe" COLLECTS_PATH="collects" + GUI_COLLECTS_PATH="../collects" CONFIG_PATH="etc" + GUI_CONFIG_PATH="../etc" skip_iconv_check=yes check_for_mprotect=no AC_DEFINE(HAVE_STDINT_H,1,[Have stdint.h]) @@ -1741,7 +1746,9 @@ AC_SUBST(etcpltdir) AC_SUBST(includepltdir) AC_SUBST(docdir) AC_SUBST(COLLECTS_PATH) +AC_SUBST(GUI_COLLECTS_PATH) AC_SUBST(CONFIG_PATH) +AC_SUBST(GUI_CONFIG_PATH) AC_SUBST(MMM) AC_SUBST(MMM_INSTALLED) From 9aba66b608b27aab9fc7465d024e99f65d13e140 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 30 Aug 2015 08:14:04 -0600 Subject: [PATCH 127/381] makefile target for creating a native executable for cross compiling --- Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Makefile b/Makefile index 842eb0ba36..5c6d46272c 100644 --- a/Makefile +++ b/Makefile @@ -172,6 +172,17 @@ win32-remove-setup-dlls: racket/src/build/Makefile: racket/src/configure racket/src/Makefile.in cd racket/src/build; ../configure $(CONFIGURE_ARGS_qq) + +# For cross-compilation, build a native executable with no configure options: +native-for-cross: + mkdir -p racket/src/build/cross + $(MAKE) racket/src/build/cross/Makefile + cd racket/src/build/cross; $(MAKE) reconfigure + cd racket/src/build/cross/racket; $(MAKE) + +racket/src/build/cross/Makefile: racket/src/configure racket/src/Makefile.in + cd racket/src/build/cross; ../../configure + # ------------------------------------------------------------ # Configuration options for building installers From 73e5313e1c1aaa4ae864aea97334a08a09e92cb6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 30 Aug 2015 10:58:07 -0600 Subject: [PATCH 128/381] fix starter icons for Windows cross-compile --- racket/src/racket/Makefile.in | 5 ----- racket/src/racket/dynsrc/Makefile.in | 8 +++++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 1efdba7a87..91bb9d6645 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -280,11 +280,6 @@ ee-main: ee-app: $(RACKET) main_ee.@LTO@ if [ "$(EEAPP)" = '' ] ; then echo "ERROR: You must specify EEAPP" ; else $(CC) $(MAIN_CFLAGS_NODBG) -o $(EEAPP) main_ee.@LTO@ $(EEOBJECTS) $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LIBS@ ; fi -mzstart.exe: $(srcdir)/dynsrc/start.c - $(CC) $(CFLAGS) $(CPPFLAGS) -o mzstart.exe $(srcdir)/dynsrc/start.c - -starter: mzstart.exe - MZCOM_DEPS = $(MAIN_HEADER_DEPS) $(srcdir)/../mzcom/com_glue.h $(srcdir)/../mzcom/resource.h mzcom.@LTO@: $(srcdir)/../mzcom/mzcom.cxx $(MZCOM_DEPS) diff --git a/racket/src/racket/dynsrc/Makefile.in b/racket/src/racket/dynsrc/Makefile.in index 5c88395a92..2fbfa887dd 100644 --- a/racket/src/racket/dynsrc/Makefile.in +++ b/racket/src/racket/dynsrc/Makefile.in @@ -57,11 +57,13 @@ dynexmpl.o: $(srcdir)/dynexmpl.c $(HEADERS) ../starter@MINGW@@EXE_SUFFIX@: $(srcdir)/start.c ../mrstarter@EXE_SUFFIX@ sres.o $(PLAIN_CC) $(ALL_CFLAGS) -o ../starter@EXE_SUFFIX@ $(srcdir)/start.c sres.o -../mrstarter@EXE_SUFFIX@: sres.o - $(PLAIN_CC) $(ALL_CFLAGS) -mwindows -DMRSTART -o ../mrstarter@EXE_SUFFIX@ $(srcdir)/start.c sres.o +../mrstarter@EXE_SUFFIX@: smrres.o + $(PLAIN_CC) $(ALL_CFLAGS) -mwindows -DMRSTART -o ../mrstarter@EXE_SUFFIX@ $(srcdir)/start.c smrres.o sres.o: - @WINDRES@ -i $(srcdir)/../../worksp/starters/start.rc -o sres.o + @WINDRES@ -DMZSTART -i $(srcdir)/../../worksp/starters/start.rc -o sres.o +smrres.o: + @WINDRES@ -DMRSTART -i $(srcdir)/../../worksp/starters/start.rc -o smrres.o # Cygwin ######################################## From 9c0b6593b6f4478933cb6132b1af22c643938993 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 30 Aug 2015 12:20:40 -0600 Subject: [PATCH 129/381] filesystem-change-evt: wide paths for Windows --- racket/src/racket/src/port.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index de69a09505..6645310f9f 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -6105,12 +6105,12 @@ Scheme_Object *scheme_filesystem_change_evt(Scheme_Object *path, int flags, int char *try_filename = filename; while (1) { - h = FindFirstChangeNotification(try_filename, FALSE, - (FILE_NOTIFY_CHANGE_FILE_NAME - | FILE_NOTIFY_CHANGE_DIR_NAME - | FILE_NOTIFY_CHANGE_SIZE - | FILE_NOTIFY_CHANGE_LAST_WRITE - | FILE_NOTIFY_CHANGE_ATTRIBUTES)); + h = FindFirstChangeNotificationW(WIDE_PATH(try_filename), FALSE, + (FILE_NOTIFY_CHANGE_FILE_NAME + | FILE_NOTIFY_CHANGE_DIR_NAME + | FILE_NOTIFY_CHANGE_SIZE + | FILE_NOTIFY_CHANGE_LAST_WRITE + | FILE_NOTIFY_CHANGE_ATTRIBUTES)); if (h == INVALID_HANDLE_VALUE) { /* If `filename' refers to a file, then monitor its enclosing directory. */ errid = GetLastError(); From 38317b87c2742236b734b1295a1a8fa11bd49ebb Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Mon, 31 Aug 2015 15:32:36 -0600 Subject: [PATCH 130/381] setting the imported flag on toplevels --- racket/src/racket/src/resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index ee46cc00cc..7cae5be45f 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -3777,7 +3777,7 @@ static Comp_Prefix *unresolve_prefix(Resolve_Prefix *rp, Unresolve_Info *ui) { mv = unresolve_prefix_symbol(rp->toplevels[i], ui); o = scheme_register_toplevel_in_comp_prefix(mv, cp, 0, NULL); } else { - o = scheme_register_toplevel_in_comp_prefix(rp->toplevels[i], cp, 0, NULL); + o = scheme_register_toplevel_in_comp_prefix(rp->toplevels[i], cp, 1, NULL); } scheme_hash_set(ui->toplevels, scheme_make_integer(SCHEME_TOPLEVEL_POS(o)), o); } From f09c78b5f4134ab738a272ac4b67be1ee3671eb1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 31 Aug 2015 16:20:52 -0600 Subject: [PATCH 131/381] racket/unit: fix `#:omit-constructor` Closes #1006, with a test case based on that report. --- pkgs/racket-test/tests/units/test-unit.rkt | 14 ++++++++++++++ racket/collects/racket/unit.rkt | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/units/test-unit.rkt b/pkgs/racket-test/tests/units/test-unit.rkt index c460883198..1d13a9b1fd 100644 --- a/pkgs/racket-test/tests/units/test-unit.rkt +++ b/pkgs/racket-test/tests/units/test-unit.rkt @@ -2185,3 +2185,17 @@ (test '(0 0) (dynamic-require ''check-define-values-invoke-unit-spec 'results)) ;; ---------------------------------------- + + (let ((s 1)) + (define-signature sig (an-s (struct s (x y) #:omit-constructor))) + (test '(1 2) + (invoke-unit + (compound-unit (import) (export) + (link (((S : sig)) (unit (import) (export sig) + (define-struct s (x y)) + (define an-s (s 1 2)))) + (() (unit (import sig) (export) + (match an-s + [(s x y) (list x y)])) + S)))))) + diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index c9e609c386..a865dbbe9e 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -270,7 +270,9 @@ (cons opt-cname opt-cname))] [extra-make? #f] [else (cons def-cname #'name)])] - [(self-ctr?) (and cname (bound-identifier=? #'name (cdr cname)))]) + [(self-ctr?) (and cname + (bound-identifier=? #'name (cdr cname)) + (not no-ctr?))]) (cons #`(define-syntaxes (name) #,(let ([e (build-struct-expand-info From 13964c4141a186ae310adda33abf433ea4c3384e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 31 Aug 2015 20:30:17 -0500 Subject: [PATCH 132/381] add and use late-neg projections to the contract system These avoid one layer of currying and are more efficient, getting about a 1.3x speed up on this program: #lang racket/base (module server racket/base (require racket/contract/base) (provide (contract-out [f (-> integer? boolean? char? void?)])) (define (f i b c) (void))) (require (submod "." server)) (time (for ([x (in-range 10000000)]) (f 1 #t #\x))) --- .../scribblings/reference/contracts.scrbl | 46 +- .../racket/contract/private/arr-i.rkt | 6 + .../contract/private/arrow-higher-order.rkt | 115 ++-- .../contract/private/arrow-val-first.rkt | 63 ++- .../collects/racket/contract/private/base.rkt | 6 +- .../collects/racket/contract/private/box.rkt | 52 +- .../collects/racket/contract/private/guts.rkt | 20 +- .../collects/racket/contract/private/hash.rkt | 93 ++-- .../collects/racket/contract/private/misc.rkt | 490 +++++++++--------- .../collects/racket/contract/private/orc.rkt | 53 +- .../collects/racket/contract/private/prop.rkt | 27 +- .../racket/contract/private/vector.rkt | 106 ++-- 12 files changed, 570 insertions(+), 507 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index f5983d411d..f1dbde8969 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -1831,7 +1831,11 @@ accepted by the third argument to @racket[datum->syntax]. @defproc[(make-contract [#:name name any/c 'anonymous-contract] [#:first-order test (-> any/c any/c) (λ (x) #t)] - [#:val-first-projection + [#:late-neg-projection + late-neg-proj + (or/c #f (-> blame? (-> any/c any/c any/c))) + #f] + [#:val-first-projection val-first-proj (or/c #f (-> blame? (-> any/c (-> any/c any/c)))) #f] @@ -1852,6 +1856,10 @@ accepted by the third argument to @racket[datum->syntax]. @defproc[(make-chaperone-contract [#:name name any/c 'anonymous-chaperone-contract] [#:first-order test (-> any/c any/c) (λ (x) #t)] + [#:late-neg-projection + late-neg-proj + (or/c #f (-> blame? (-> any/c any/c any/c))) + #f] [#:val-first-projection val-first-proj (or/c #f (-> blame? (-> any/c (-> any/c any/c)))) @@ -1873,6 +1881,10 @@ accepted by the third argument to @racket[datum->syntax]. @defproc[(make-flat-contract [#:name name any/c 'anonymous-flat-contract] [#:first-order test (-> any/c any/c) (λ (x) #t)] + [#:late-neg-projection + late-neg-proj + (or/c #f (-> blame? (-> any/c any/c any/c))) + #f] [#:val-first-projection val-first-proj (or/c #f (-> blame? (-> any/c (-> any/c any/c)))) @@ -1893,12 +1905,6 @@ accepted by the third argument to @racket[datum->syntax]. flat-contract?] )]{ - @italic{The precise details of the - @racket[val-first-projection] argument - are subject to change. (Probably - also the default values of the @racket[project] - arguments will change.} - These functions build simple higher-order contracts, chaperone contracts, and flat contracts, respectively. They both take the same set of three optional arguments: a name, a first-order predicate, and a blame-tracking projection. @@ -1916,13 +1922,25 @@ by @racket[contract-first-order-passes?], and indirectly by @racket[or/c] to determine which of multiple higher-order contracts to wrap a value with. The default test accepts any value. -The projection @racket[proj] defines the behavior of applying the contract. It +The @racket[late-neg-proj] defines the behavior of applying the contract. If it is +supplied, it accepts a blame object that does not have a value for + the @racket[blame-negative] field. Then it must return a function that accepts + both the value that is getting the contract and the name of the blame party, in + that order. The result must either be the value (perhaps suitably wrapped + with a @tech{chaperone} or @tech{impersonator} to enforce the contract), or + signal a contract violation using @racket[raise-blame-error]. The default is + @racket[#f]. + +The projection @racket[proj] and @racket[val-first-proj] are older mechanisms for + defining the behavior of applying the contract. The @racket[proj] argument is a curried function of two arguments: the first application accepts a blame object, and the second accepts a value to protect with the contract. The projection must either produce the value, suitably wrapped to enforce any higher-order aspects of the contract, or signal a contract violation using @racket[raise-blame-error]. The default projection produces an error when the first-order test fails, and produces the value unchanged otherwise. +The @racket[val-first-proj] is like @racket[late-neg-proj], except with +an extra layer of currying. Projections for chaperone contracts must produce a value that passes @racket[chaperone-of?] when compared with the original, uncontracted value. @@ -2274,6 +2292,10 @@ is expected to be the blame record for the contract on the value). get-first-order (-> contract? (-> any/c boolean?)) (λ (c) (λ (x) #t))] + [#:late-neg-projection + late-neg-proj + (or/c #f (-> contract? (-> blame? (-> any/c any/c any/c)))) + #f] [#:val-first-projection val-first-proj (or/c #f (-> contract? blame? (-> any/c (-> any/c any/c)))) @@ -2323,6 +2345,10 @@ is expected to be the blame record for the contract on the value). get-first-order (-> contract? (-> any/c boolean?)) (λ (c) (λ (x) #t))] + [#:late-neg-projection + late-neg-proj + (or/c #f (-> contract? blame? (-> any/c any/c any/c))) + #f] [#:val-first-projection val-first-proj (or/c #f (-> contract? blame? (-> any/c (-> any/c any/c)))) @@ -2372,6 +2398,10 @@ is expected to be the blame record for the contract on the value). get-first-order (-> contract? (-> any/c boolean?)) (λ (c) (λ (x) #t))] + [#:late-neg-projection + late-neg-proj + (or/c #f (-> contract? blame? (-> any/c any/c any/c))) + #f] [#:val-first-projection val-first-proj (or/c #f (-> contract? blame? (-> any/c (-> any/c any/c)))) diff --git a/racket/collects/racket/contract/private/arr-i.rkt b/racket/collects/racket/contract/private/arr-i.rkt index eed7834476..e3f6ff3159 100644 --- a/racket/collects/racket/contract/private/arr-i.rkt +++ b/racket/collects/racket/contract/private/arr-i.rkt @@ -195,6 +195,12 @@ (λ (neg-party) ((blame-accepting-proj (blame-add-missing-party blame neg-party)) val)) (->i-mk-val-first-wrapper ctc))))) + #:late-neg-projection + (λ (ctc) + (define blame-accepting-proj (arr->i-proj ctc)) + (λ (blame) + (λ (val neg-party) + ((blame-accepting-proj (blame-add-missing-party blame neg-party)) val)))) #:projection arr->i-proj #:name (λ (ctc) (define (arg/ress->spec infos ctcs dep-ctcs skip?) diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index 20a2eade0e..f8b8f4ae64 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -163,7 +163,7 @@ (list (with-syntax ([rng-len (length rngs)]) (with-syntax ([rng-results - #'(values ((rng-ctc rng-x) neg-party) + #'(values (rng-ctc rng-x neg-party) ...)]) #'(case-lambda [(rng-x ...) @@ -185,7 +185,7 @@ [opt-keywords (map (λ (p) (syntax-e (car p))) opt-kwds)] [need-apply-values? (or dom-rest (not (null? opt-doms)))] [no-rng-checking? (not rngs)]) - (with-syntax ([(dom-projd-args ...) #'(((dom-ctc dom-x) neg-party) ...)] + (with-syntax ([(dom-projd-args ...) #'((dom-ctc dom-x neg-party) ...)] [basic-params (cond [dom-rest @@ -197,10 +197,10 @@ [else #'(this-param ... dom-x ... [opt-dom-x arrow:unspecified-dom] ...)])] [opt+rest-uses - (for/fold ([i (if dom-rest #'((rest-ctc rest-x) neg-party) #'null)]) + (for/fold ([i (if dom-rest #'(rest-ctc rest-x neg-party) #'null)]) ([o (in-list (reverse (syntax->list - #'(((opt-dom-ctc opt-dom-x) neg-party) ...))))] + #'((opt-dom-ctc opt-dom-x neg-party) ...))))] [opt-dom-x (in-list (reverse (syntax->list #'(opt-dom-x ...))))]) #`(let ([r #,i]) (if (eq? arrow:unspecified-dom #,opt-dom-x) r (cons #,o r))))] @@ -214,7 +214,7 @@ [kwd-stx (let* ([req-stxs (map (λ (s) (λ (r) #`(cons #,s #,r))) - (syntax->list #'(((req-kwd-ctc req-kwd-x) neg-party) ...)))] + (syntax->list #'((req-kwd-ctc req-kwd-x neg-party) ...)))] [opt-stxs (map (λ (x c) (λ (r) #`(maybe-cons-kwd #,c #,x #,r neg-party))) (syntax->list #'(opt-kwd-x ...)) @@ -348,40 +348,42 @@ (define (maybe-cons-kwd c x r neg-party) (if (eq? arrow:unspecified-dom x) r - (cons ((c x) neg-party) r))) + (cons (c x neg-party) r))) (define (->-proj chaperone-or-impersonate-procedure ctc ;; fields of the 'ctc' struct min-arity doms kwd-infos rest pre? rngs post? - plus-one-arity-function chaperone-constructor) - (define doms-proj (map get/build-val-first-projection doms)) - (define rest-proj (and rest (get/build-val-first-projection rest))) - (define rngs-proj (if rngs (map get/build-val-first-projection rngs) '())) - (define kwds-proj - (for/list ([kwd-info (in-list kwd-infos)]) - (get/build-val-first-projection (kwd-info-ctc kwd-info)))) + plus-one-arity-function chaperone-constructor + late-neg?) (define optionals-length (- (length doms) min-arity)) (define mtd? #f) ;; not yet supported for the new contracts (λ (orig-blame) (define rng-blame (arrow:blame-add-range-context orig-blame)) (define swapped-domain (blame-add-context orig-blame "the domain of" #:swap? #t)) - (define partial-doms - (for/list ([dom (in-list doms-proj)] + + (define partial-doms + (for/list ([dom (in-list doms)] [n (in-naturals 1)]) - (dom (blame-add-context orig-blame - (format "the ~a argument of" (n->th n)) - #:swap? #t)))) - (define partial-rest (and rest-proj - (rest-proj + ((get/build-late-neg-projection dom) + (blame-add-context orig-blame + (format "the ~a argument of" (n->th n)) + #:swap? #t)))) + (define partial-rest (and rest + ((get/build-late-neg-projection rest) (blame-add-context orig-blame "the rest argument of" #:swap? #t)))) - (define partial-ranges (map (λ (rng) (rng rng-blame)) rngs-proj)) + (define partial-ranges + (if rngs + (for/list ([rng (in-list rngs)]) + ((get/build-late-neg-projection rng) rng-blame)) + '())) (define partial-kwds - (for/list ([kwd-proj (in-list kwds-proj)] + (for/list ([kwd-info (in-list kwd-infos)] [kwd (in-list kwd-infos)]) - (kwd-proj (blame-add-context orig-blame - (format "the ~a argument of" (kwd-info-kwd kwd)) - #:swap? #t)))) + ((get/build-late-neg-projection (kwd-info-ctc kwd-info)) + (blame-add-context orig-blame + (format "the ~a argument of" (kwd-info-kwd kwd)) + #:swap? #t)))) (define man-then-opt-partial-kwds (append (for/list ([partial-kwd (in-list partial-kwds)] [kwd-info (in-list kwd-infos)] @@ -401,27 +403,42 @@ man-then-opt-partial-kwds partial-ranges (if partial-rest (list partial-rest) '()))) - (λ (val) - (wrapped-extra-arg-arrow - (cond - [(do-arity-checking orig-blame val doms rest min-arity kwd-infos) - => - values] - [else - (λ (neg-party) - (define chap/imp-func (apply chaperone-constructor orig-blame val neg-party the-args)) - (if post? - (chaperone-or-impersonate-procedure - val - chap/imp-func - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party orig-blame neg-party)) - (chaperone-or-impersonate-procedure - val - chap/imp-func - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party orig-blame neg-party) - impersonator-prop:application-mark (cons arrow:contract-key - ;; is this right? - partial-ranges))))]) - (apply plus-one-arity-function orig-blame val plus-one-constructor-args))))) + + (define (successfully-got-the-right-kind-of-function val neg-party) + (define chap/imp-func (apply chaperone-constructor orig-blame val neg-party the-args)) + (if post? + (chaperone-or-impersonate-procedure + val + chap/imp-func + impersonator-prop:contracted ctc + impersonator-prop:blame (blame-add-missing-party orig-blame neg-party)) + (chaperone-or-impersonate-procedure + val + chap/imp-func + impersonator-prop:contracted ctc + impersonator-prop:blame (blame-add-missing-party orig-blame neg-party) + impersonator-prop:application-mark (cons arrow:contract-key + ;; is this right? + partial-ranges)))) + + (cond + [late-neg? + (λ (val neg-party) + (cond + [(do-arity-checking orig-blame val doms rest min-arity kwd-infos) + => + (λ (f) + (f neg-party))] + [else + (successfully-got-the-right-kind-of-function val neg-party)]))] + [else + (λ (val) + (wrapped-extra-arg-arrow + (cond + [(do-arity-checking orig-blame val doms rest min-arity kwd-infos) + => + values] + [else + (λ (neg-party) + (successfully-got-the-right-kind-of-function val neg-party))]) + (apply plus-one-arity-function orig-blame val plus-one-constructor-args)))]))) diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index 92159a55bf..c77351bd24 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -179,7 +179,7 @@ [(res-x ...) (generate-temporaries (or rngs '()))] [(kwd-arg-x ...) (generate-temporaries mandatory-kwds)]) - (define base-arg-expressions (reverse (syntax->list #'(((regb arg-x) neg-party) ...)))) + (define base-arg-expressions (reverse (syntax->list #'((regb arg-x neg-party) ...)))) (define normal-arg-vars (generate-temporaries #'(arg-x ...))) (define base-arg-vars normal-arg-vars) @@ -190,7 +190,7 @@ append (map (λ (kwd kwd-arg-x kb) (set! base-arg-expressions - (cons #`((#,kb #,kwd-arg-x) neg-party) + (cons #`(#,kb #,kwd-arg-x neg-party) base-arg-expressions)) (set! base-arg-vars (cons (car (generate-temporaries (list kwd-arg-x))) base-arg-vars)) @@ -228,7 +228,7 @@ #,@(for/list ([ob (in-list (reverse ob))] [optional-arg (in-list (reverse optional-args))]) (set! args-expressions - (cons #`((#,ob #,optional-arg) neg-party) + (cons #`(#,ob #,optional-arg neg-party) args-expressions)) (set! args-vars (cons (car (generate-temporaries (list optional-arg))) @@ -237,7 +237,7 @@ (define full-call (cond [(and first? rest) - (set! args-expressions (cons #'((restb rest-arg) neg-party) args-expressions)) + (set! args-expressions (cons #'(restb rest-arg neg-party) args-expressions)) (set! args-vars (cons (car (generate-temporaries '(rest-args-arrow-contract))) args-vars)) #`(apply #,@no-rest-call #,(car args-vars))] @@ -281,7 +281,9 @@ #'(res-x ...))))] [else post-check ... - (values ((rb res-x) neg-party) ...)])))] + (values + (rb res-x neg-party) + ...)])))] #`[#,the-args pre-check ... (let ([blame+neg-party (cons blame neg-party)]) @@ -340,7 +342,7 @@ (cond [(and (pair? mandatory-kwds) (equal? (car mandatory-kwds) kwd)) - (cons (((car kbs) kwd-arg) neg-party) + (cons ((car kbs) kwd-arg neg-party) (loop (cdr kwds) (cdr kwd-args) (cdr mandatory-kwds) @@ -349,7 +351,7 @@ okbs))] [(and (pair? optional-kwds) (equal? (car optional-kwds) kwd)) - (cons (((car okbs) kwd-arg) neg-party) + (cons ((car okbs) kwd-arg neg-party) (loop (cdr kwds) (cdr kwd-args) mandatory-kwds @@ -368,9 +370,9 @@ [rbs rbs]) (cond [(null? regular-args) '()] - [(null? rbs) ((rest-ctc regular-args) neg-party)] + [(null? rbs) (rest-ctc regular-args neg-party)] [else - (cons (((car rbs) (car regular-args)) neg-party) + (cons ((car rbs) (car regular-args) neg-party) (loop (cdr regular-args) (cdr rbs)))])))) (define complete-blame (blame-add-missing-party blame neg-party)) (when pre (check-pre-cond pre blame neg-party f)) @@ -385,7 +387,7 @@ values (for/list ([result (in-list results)] [rng (in-list rngs)]) - ((rng result) neg-party)))] + (rng result neg-party)))] [else (mk-call)])))) @@ -908,16 +910,16 @@ (define kwd-results (for/list ([kwd (in-list kwds)] [kwd-arg (in-list kwd-args)]) - (((hash-ref kwd-table kwd) kwd-arg) neg-party))) + ((hash-ref kwd-table kwd) kwd-arg neg-party))) (define regular-arg-results (let loop ([args args] [projs mandatory+optional-dom-projs]) (cond [(and (null? projs) (null? args)) '()] [(null? projs) - ((rest-proj args) neg-party)] + (rest-proj args neg-party)] [(null? args) (error 'cant-happen::dynamic->*)] - [else (cons (((car projs) (car args)) neg-party) + [else (cons ((car projs) (car args) neg-party) (loop (cdr args) (cdr projs)))]))) (define (result-checker . results) (unless (= rng-len (length results)) @@ -926,7 +928,7 @@ values (for/list ([res (in-list results)] [neg-party-proj (in-list rng-projs)]) - ((neg-party-proj res) neg-party)))) + (neg-party-proj res neg-party)))) (define args-dealt-with (if (null? kwds) regular-arg-results @@ -1132,7 +1134,7 @@ #t)) (define (make-property build-X-property chaperone-or-impersonate-procedure) - (define proj + (define val-first-proj (λ (->stct) (->-proj chaperone-or-impersonate-procedure ->stct (base->-min-arity ->stct) @@ -1143,14 +1145,28 @@ (base->-rngs ->stct) (base->-post? ->stct) (base->-plus-one-arity-function ->stct) - (base->-chaperone-constructor ->stct)))) + (base->-chaperone-constructor ->stct) + #f))) + (define late-neg-proj + (λ (->stct) + (->-proj chaperone-or-impersonate-procedure ->stct + (base->-min-arity ->stct) + (base->-doms ->stct) + (base->-kwd-infos ->stct) + (base->-rest ->stct) + (base->-pre? ->stct) + (base->-rngs ->stct) + (base->-post? ->stct) + (base->-plus-one-arity-function ->stct) + (base->-chaperone-constructor ->stct) + #t))) (parameterize ([skip-projection-wrapper? #t]) (build-X-property #:name base->-name #:first-order ->-first-order #:projection (λ (this) - (define cthis (proj this)) + (define cthis (val-first-proj this)) (λ (blame) (define cblame (cthis blame)) (λ (val) @@ -1180,7 +1196,8 @@ (not (base->-post? that)))) #:generate ->-generate #:exercise ->-exercise - #:val-first-projection proj))) + #:val-first-projection val-first-proj + #:late-neg-projection late-neg-proj))) (define-struct (-> base->) () #:property @@ -1207,11 +1224,11 @@ (λ () (f)) (case-lambda [(rng) - (unless (void? rng) - (raise-blame-error blame #:missing-party neg-party rng - '(expected: "void?" given: "~e") - rng)) - rng] + (if (void? rng) + rng + (raise-blame-error blame #:missing-party neg-party rng + '(expected: "void?" given: "~e") + rng))] [args (wrong-number-of-results-blame blame neg-party f args 1)])))) (get-chaperone-constructor)))) diff --git a/racket/collects/racket/contract/private/base.rkt b/racket/collects/racket/contract/private/base.rkt index 84d3fd87cc..aee46da156 100644 --- a/racket/collects/racket/contract/private/base.rkt +++ b/racket/collects/racket/contract/private/base.rkt @@ -51,7 +51,7 @@ (define (apply-contract c v pos neg name loc) (let ([c (coerce-contract 'contract c)]) (check-source-location! 'contract loc) - (define cvfp (contract-val-first-projection c)) + (define clnp (contract-late-neg-projection c)) (define blame (make-blame (build-source-location loc) name @@ -65,10 +65,10 @@ ;; instead of changing the library around. (or pos "false") - (if cvfp #f neg) + (if clnp #f neg) #t)) (cond - [cvfp (((cvfp blame) v) neg)] + [clnp ((clnp blame) v neg)] [else (((contract-projection c) blame) v)]))) (define-syntax (invariant-assertion stx) diff --git a/racket/collects/racket/contract/private/box.rkt b/racket/collects/racket/contract/private/box.rkt index ce926be82c..b6a8bd8ef7 100644 --- a/racket/collects/racket/contract/private/box.rkt +++ b/racket/collects/racket/contract/private/box.rkt @@ -111,18 +111,19 @@ #:name box/c-name #:first-order box/c-first-order #:stronger box/c-stronger - #:val-first-projection + #:late-neg-projection (λ (ctc) - (define content-ctc (get/build-val-first-projection (base-box/c-content ctc))) + (define content-ctc (get/build-late-neg-projection (base-box/c-content ctc))) (λ (blame) (define box-blame (add-box-context blame)) - (define val-first-proj (content-ctc box-blame)) - (λ (val) - (define fail-proc (check-box/c-np ctc val blame)) - (or fail-proc - (λ (neg-party) - ((val-first-proj (unbox val)) neg-party) - val))))) + (define late-neg-proj (content-ctc box-blame)) + (λ (val neg-party) + (define fail-proc (check-box/c-np ctc val box-blame)) + (cond + [fail-proc (fail-proc neg-party)] + [else + (late-neg-proj (unbox val) neg-party) + val])))) #:projection (λ (ctc) (λ (blame) @@ -148,26 +149,29 @@ impersonator-prop:contracted ctc impersonator-prop:blame blame)))))))) -(define (ho-val-first-projection chaperone/impersonate-box) +(define (ho-late-neg-projection chaperone/impersonate-box) (λ (ctc) (define elem-ctc (base-box/c-content ctc)) (define immutable (base-box/c-immutable ctc)) - (define vfp (get/build-val-first-projection elem-ctc)) + (define vfp (get/build-late-neg-projection elem-ctc)) (λ (blame) (define box-blame (add-box-context blame)) (define pos-elem-proj (vfp box-blame)) (define neg-elem-proj (vfp (blame-swap box-blame))) - (λ (val) - (or (check-box/c-np ctc val blame) - (if (and (immutable? val) (not (chaperone? val))) - (λ (neg-party) (box-immutable ((pos-elem-proj (unbox val)) neg-party))) - (λ (neg-party) - (chaperone/impersonate-box - val - (λ (b v) ((pos-elem-proj v) neg-party)) - (λ (b v) ((neg-elem-proj v) neg-party)) - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party blame neg-party))))))))) + (λ (val neg-party) + (cond + [(check-box/c-np ctc val blame) + => + (λ (f) (f neg-party))] + [else + (if (and (immutable? val) (not (chaperone? val))) + (box-immutable (pos-elem-proj (unbox val) neg-party)) + (chaperone/impersonate-box + val + (λ (b v) (pos-elem-proj v neg-party)) + (λ (b v) (neg-elem-proj v neg-party)) + impersonator-prop:contracted ctc + impersonator-prop:blame (blame-add-missing-party blame neg-party)))]))))) (define-struct (chaperone-box/c base-box/c) () #:property prop:custom-write custom-write-property-proc @@ -176,7 +180,7 @@ #:name box/c-name #:first-order box/c-first-order #:stronger box/c-stronger - #:val-first-projection (ho-val-first-projection chaperone-box) + #:late-neg-projection (ho-late-neg-projection chaperone-box) #:projection (ho-projection chaperone-box))) (define-struct (impersonator-box/c base-box/c) () @@ -186,7 +190,7 @@ #:name box/c-name #:first-order box/c-first-order #:stronger box/c-stronger - #:val-first-projection (ho-val-first-projection impersonate-box) + #:late-neg-projection (ho-late-neg-projection impersonate-box) #:projection (ho-projection impersonate-box))) (define-syntax (wrap-box/c stx) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index a804c13436..417b8a7cf6 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -544,22 +544,18 @@ (predicate-contract-pred that)))) #:name (λ (ctc) (predicate-contract-name ctc)) #:first-order (λ (ctc) (predicate-contract-pred ctc)) - #:val-first-projection + #:late-neg-projection (λ (ctc) (define p? (predicate-contract-pred ctc)) (define name (predicate-contract-name ctc)) (λ (blame) - (let ([predicate-contract-proj - (λ (v) - (if (p? v) - (λ (neg-party) - v) - (λ (neg-party) - (raise-blame-error blame v #:missing-party neg-party - '(expected: "~s" given: "~e") - name - v))))]) - predicate-contract-proj))) + (λ (v neg-party) + (if (p? v) + v + (raise-blame-error blame v #:missing-party neg-party + '(expected: "~s" given: "~e") + name + v))))) #:generate (λ (ctc) (let ([generate (predicate-contract-generate ctc)]) (cond diff --git a/racket/collects/racket/contract/private/hash.rkt b/racket/collects/racket/contract/private/hash.rkt index 9f4d0cb616..b5f9005c8e 100644 --- a/racket/collects/racket/contract/private/hash.rkt +++ b/racket/collects/racket/contract/private/hash.rkt @@ -188,7 +188,7 @@ #:name hash/c-name #:first-order hash/c-first-order #:stronger hash/c-stronger - #:val-first-projection + #:late-neg-projection (λ (ctc) (define dom-ctc (base-hash/c-dom ctc)) (define immutable (base-hash/c-immutable ctc)) @@ -198,38 +198,36 @@ (blame-add-key-context blame #f))) (define rng-proj ((contract-projection (base-hash/c-rng ctc)) (blame-add-value-context blame #f))) - (λ (val) - (λ (neg-party) - (cond - [(check-hash/c dom-ctc immutable flat? val blame neg-party) - val] - [else - (for ([(k v) (in-hash val)]) - (dom-proj k) - (rng-proj v)) - val]))))))) + (λ (val neg-party) + (cond + [(check-hash/c dom-ctc immutable flat? val blame neg-party) + val] + [else + (for ([(k v) (in-hash val)]) + (dom-proj k) + (rng-proj v)) + val])))))) (define (ho-projection chaperone-or-impersonate-hash) (λ (ctc) (define immutable (base-hash/c-immutable ctc)) (define dom-ctc (base-hash/c-dom ctc)) (define flat? (flat-hash/c? ctc)) - (define dom-proc (get/build-val-first-projection dom-ctc)) - (define rng-proc (get/build-val-first-projection (base-hash/c-rng ctc))) + (define dom-proc (get/build-late-neg-projection dom-ctc)) + (define rng-proc (get/build-late-neg-projection (base-hash/c-rng ctc))) (λ (blame) (define pos-dom-proj (dom-proc (blame-add-key-context blame #f))) (define neg-dom-proj (dom-proc (blame-add-key-context blame #t))) (define pos-rng-proj (rng-proc (blame-add-value-context blame #f))) (define neg-rng-proj (rng-proc (blame-add-value-context blame #t))) - (λ (val) - (λ (neg-party) - (cond - [(check-hash/c dom-ctc immutable flat? val blame neg-party) - val] - [else - (handle-the-hash val neg-party - pos-dom-proj neg-dom-proj (λ (v) pos-rng-proj) (λ (v) neg-rng-proj) - chaperone-or-impersonate-hash ctc blame)])))))) + (λ (val neg-party) + (cond + [(check-hash/c dom-ctc immutable flat? val blame neg-party) + val] + [else + (handle-the-hash val neg-party + pos-dom-proj neg-dom-proj (λ (v) pos-rng-proj) (λ (v) neg-rng-proj) + chaperone-or-impersonate-hash ctc blame)]))))) (define (blame-add-key-context blame swap?) (blame-add-context blame "the keys of" #:swap? swap?)) (define (blame-add-value-context blame swap?) (blame-add-context blame "the values of" #:swap? swap?)) @@ -240,21 +238,21 @@ (if (immutable? val) (for/fold ([h val]) ([(k v) (in-hash val)]) (hash-set h - ((pos-dom-proj k) neg-party) - (((mk-pos-rng-proj k) v) neg-party))) + (pos-dom-proj k neg-party) + ((mk-pos-rng-proj k) v neg-party))) (chaperone-or-impersonate-hash val (λ (h k) - (values ((neg-dom-proj k) neg-party) + (values (neg-dom-proj k neg-party) (λ (h k v) - (((mk-pos-rng-proj k) v) neg-party)))) + ((mk-pos-rng-proj k) v neg-party)))) (λ (h k v) - (values ((neg-dom-proj k) neg-party) - (((mk-neg-rng-proj k) v) neg-party))) + (values (neg-dom-proj k neg-party) + ((mk-neg-rng-proj k) v neg-party))) (λ (h k) - ((neg-dom-proj k) neg-party)) + (neg-dom-proj k neg-party)) (λ (h k) - ((pos-dom-proj k) neg-party)) + (pos-dom-proj k neg-party)) impersonator-prop:contracted ctc impersonator-prop:blame blame))) @@ -266,7 +264,7 @@ #:name hash/c-name #:first-order hash/c-first-order #:stronger hash/c-stronger - #:val-first-projection (ho-projection chaperone-hash))) + #:late-neg-projection (ho-projection chaperone-hash))) (define-struct (impersonator-hash/c base-hash/c) () #:omit-define-syntaxes @@ -276,7 +274,7 @@ #:name hash/c-name #:first-order hash/c-first-order #:stronger hash/c-stronger - #:val-first-projection (ho-projection impersonate-hash))) + #:late-neg-projection (ho-projection impersonate-hash))) (define (hash/dc-name a-hash-dc) @@ -305,11 +303,11 @@ (define (hash/dc-stronger this that) #f) -(define ((hash/dc-val-first-projection chaperone-or-impersonate-hash) ctc) +(define ((hash/dc-late-neg-projection chaperone-or-impersonate-hash) ctc) (define dom-ctc (base-hash/dc-dom ctc)) (define immutable (base-hash/dc-immutable ctc)) (define flat? (flat-hash/dc? ctc)) - (define dom-proc (get/build-val-first-projection dom-ctc)) + (define dom-proc (get/build-late-neg-projection dom-ctc)) (define dep-rng-proc (base-hash/dc-dep-rng ctc)) (λ (blame) (define pos-dom-proj (dom-proc (blame-add-key-context blame #f))) @@ -319,18 +317,17 @@ (base-hash/dc-here ctc)))) (define pos-value-blame (blame-add-value-context blame #f)) (define neg-value-blame (blame-add-value-context blame #t)) - (λ (val) - (λ (neg-party) - (cond - [(check-hash/c dom-ctc immutable flat? val blame neg-party) val] - [else - (define ((mk-rng-proj x-value-blame) key) - ((get/build-val-first-projection (dep-rng-proc ((indy-dom-proj key) neg-party))) - x-value-blame)) - (handle-the-hash val neg-party - pos-dom-proj neg-dom-proj - (mk-rng-proj pos-value-blame) (mk-rng-proj neg-value-blame) - chaperone-or-impersonate-hash ctc blame)]))))) + (λ (val neg-party) + (cond + [(check-hash/c dom-ctc immutable flat? val blame neg-party) val] + [else + (define ((mk-rng-proj x-value-blame) key) + ((get/build-late-neg-projection (dep-rng-proc (indy-dom-proj key neg-party))) + x-value-blame)) + (handle-the-hash val neg-party + pos-dom-proj neg-dom-proj + (mk-rng-proj pos-value-blame) (mk-rng-proj neg-value-blame) + chaperone-or-impersonate-hash ctc blame)])))) (struct base-hash/dc (dom dep-rng here name-info immutable)) (struct flat-hash/dc base-hash/dc () @@ -348,7 +345,7 @@ #:name hash/dc-name #:first-order hash/dc-first-order #:stronger hash/dc-stronger - #:val-first-projection (hash/dc-val-first-projection chaperone-hash))) + #:late-neg-projection (hash/dc-late-neg-projection chaperone-hash))) (struct impersonator-hash/dc base-hash/dc () #:property prop:custom-write custom-write-property-proc #:property prop:contract @@ -356,7 +353,7 @@ #:name hash/dc-name #:first-order hash/dc-first-order #:stronger hash/dc-stronger - #:val-first-projection (hash/dc-val-first-projection impersonate-hash))) + #:late-neg-projection (hash/dc-late-neg-projection impersonate-hash))) (define (build-hash/dc dom dep-rng here name-info immutable kind) (unless (member kind '(flat chaperone impersonator)) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index e79536ff73..b65f3756b0 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -54,7 +54,9 @@ contract-projection contract-val-first-projection ;; might return #f (if none) + contract-late-neg-projection ;; might return #f (if none) get/build-val-first-projection ;; builds one if necc., using contract-projection + get/build-late-neg-projection contract-name n->th @@ -113,22 +115,21 @@ ([p (in-list (cdr projs))]) (λ (v) (p (proj v))))))) -(define (val-first-and-proj ctc) - (define mk-pos-projs (map get/build-val-first-projection (base-and/c-ctcs ctc))) +(define (late-neg-and-proj ctc) + (define mk-pos-projs (map get/build-late-neg-projection (base-and/c-ctcs ctc))) (λ (blame) - (define projs + (define projs (for/list ([c (in-list mk-pos-projs)] [n (in-naturals 1)]) (c (blame-add-context blame (format "the ~a conjunct of" (n->th n)))))) - (λ (val) - (λ (neg-party) - (let loop ([projs (cdr projs)] - [val (((car projs) val) neg-party)]) - (cond - [(null? projs) val] - [else - (loop (cdr projs) - (((car projs) val) neg-party))])))))) + (λ (val neg-party) + (let loop ([projs (cdr projs)] + [val ((car projs) val neg-party)]) + (cond + [(null? projs) val] + [else + (loop (cdr projs) + ((car projs) val neg-party))]))))) (define (first-order-and-proj ctc) (λ (blame) @@ -146,23 +147,23 @@ (define new-blame (blame-add-context blame "an and/c case of")) ((ctc1-proj new-blame) val)])]))))) -(define (first-order-val-first-and-proj ctc) +(define (first-order-late-neg-and-proj ctc) (define predicates (first-order-and/c-predicates ctc)) - (define ctcs (base-and/c-ctcs ctc)) + (define blame-accepters (map get/build-late-neg-projection (base-and/c-ctcs ctc))) (λ (blame) - (λ (val) + (define new-blame (blame-add-context blame "an and/c case of")) + (define projs (map (λ (f) (f new-blame)) blame-accepters)) + (λ (val neg-party) (let loop ([predicates predicates] - [ctcs ctcs]) + [projs projs]) (cond - [(null? predicates) (λ (neg-party) val)] + [(null? predicates) val] [else (cond [((car predicates) val) - (loop (cdr predicates) (cdr ctcs))] + (loop (cdr predicates) (cdr projs))] [else - (define ctc1-val-first-proj (get/build-val-first-projection (car ctcs))) - (define new-blame (blame-add-context blame "an and/c case of")) - ((ctc1-val-first-proj new-blame) val)])]))))) + ((car projs) val neg-party)])]))))) (define (and-stronger? this that) (and (base-and/c? that) @@ -264,7 +265,7 @@ #:property prop:flat-contract (build-flat-contract-property #:projection first-order-and-proj - #:val-first-projection first-order-val-first-and-proj + #:late-neg-projection first-order-late-neg-and-proj #:name and-name #:first-order and-first-order #:stronger and-stronger? @@ -275,7 +276,7 @@ (parameterize ([skip-projection-wrapper? #t]) (build-chaperone-contract-property #:projection and-proj - #:val-first-projection val-first-and-proj + #:late-neg-projection late-neg-and-proj #:name and-name #:first-order and-first-order #:stronger and-stronger? @@ -285,7 +286,7 @@ #:property prop:contract (build-contract-property #:projection and-proj - #:val-first-projection val-first-and-proj + #:late-neg-projection late-neg-and-proj #:name and-name #:first-order and-first-order #:stronger and-stronger? @@ -708,8 +709,8 @@ (elem-proj+blame x)) (raise-listof-blame-error blame val (pe-listof-ctc? ctc) #f))))]))) -(define (listof-val-first-projection ctc) - (define elem-proj (get/build-val-first-projection (listof-ctc-elem-c ctc))) +(define (listof-late-neg-projection ctc) + (define elem-proj (get/build-late-neg-projection (listof-ctc-elem-c ctc))) (define pred? (if (pe-listof-ctc? ctc) list? non-empty-list?)) @@ -718,49 +719,45 @@ (cond [(flat-listof-ctc? ctc) (if (im-listof-ctc? ctc) - (λ (val) - (λ (neg-party) - (let loop ([val val]) - (cond - [(pair? val) - ((elem-proj+blame (car val)) neg-party) - (loop (cdr val))] - [else - ((elem-proj+blame val) neg-party)])) - val)) - (λ (val) - (if (pred? val) - (λ (neg-party) - (for ([x (in-list val)]) - ((elem-proj+blame x) neg-party)) - val) - (λ (neg-party) - (raise-listof-blame-error blame val (pe-listof-ctc? ctc) neg-party)))))] + (λ (val neg-party) + (let loop ([val val]) + (cond + [(pair? val) + (elem-proj+blame (car val) neg-party) + (loop (cdr val))] + [else + (elem-proj+blame val neg-party)])) + val) + (λ (val neg-party) + (cond + [(pred? val) + (for ([x (in-list val)]) + (elem-proj+blame x neg-party)) + val] + [else + (raise-listof-blame-error blame val (pe-listof-ctc? ctc) neg-party)])))] [else - (if (im-listof-ctc? ctc) - (λ (val) - (λ (neg-party) - (let loop ([val val]) - (cond - [(pair? val) - (cons ((elem-proj+blame (car val)) neg-party) - (loop (cdr val)))] - [else - ((elem-proj+blame val) neg-party)])))) - (λ (val) - (if (pred? val) - (λ (neg-party) - (for/list ([x (in-list val)]) - ((elem-proj+blame x) neg-party))) - (λ (neg-party) - (raise-listof-blame-error blame val (pe-listof-ctc? ctc) neg-party)))))]))) + (if (im-listof-ctc? ctc) + (λ (val neg-party) + (let loop ([val val]) + (cond + [(pair? val) + (cons (elem-proj+blame (car val) neg-party) + (loop (cdr val)))] + [else + (elem-proj+blame val neg-party)]))) + (λ (val neg-party) + (if (pred? val) + (for/list ([x (in-list val)]) + (elem-proj+blame x neg-party)) + (raise-listof-blame-error blame val (pe-listof-ctc? ctc) neg-party))))]))) (define flat-prop (build-flat-contract-property #:name list-name #:first-order list-fo-check #:projection listof-projection - #:val-first-projection listof-val-first-projection + #:late-neg-projection listof-late-neg-projection #:generate listof-generate #:exercise listof-exercise #:stronger listof-stronger @@ -770,7 +767,7 @@ #:name list-name #:first-order list-fo-check #:projection listof-projection - #:val-first-projection listof-val-first-projection + #:late-neg-projection listof-late-neg-projection #:generate listof-generate #:exercise listof-exercise #:stronger listof-stronger @@ -780,7 +777,7 @@ #:name list-name #:first-order list-fo-check #:projection listof-projection - #:val-first-projection listof-val-first-projection + #:late-neg-projection listof-late-neg-projection #:generate listof-generate #:exercise listof-exercise #:stronger listof-stronger @@ -875,21 +872,20 @@ (define (blame-add-cdr-context blame) (blame-add-context blame "the cdr of")) -(define ((cons/c-val-first-ho-check combine) ctc) +(define ((cons/c-late-neg-ho-check combine) ctc) (define ctc-car (the-cons/c-hd-ctc ctc)) (define ctc-cdr (the-cons/c-tl-ctc ctc)) - (define car-val-first-proj (get/build-val-first-projection ctc-car)) - (define cdr-val-first-proj (get/build-val-first-projection ctc-cdr)) + (define car-late-neg-proj (get/build-late-neg-projection ctc-car)) + (define cdr-late-neg-proj (get/build-late-neg-projection ctc-cdr)) (λ (blame) - (define car-p (car-val-first-proj (blame-add-car-context blame))) - (define cdr-p (cdr-val-first-proj (blame-add-cdr-context blame))) - (λ (v) - (λ (neg-party) - (unless (pair? v) - (raise-not-cons-blame-error blame #:missing-party neg-party v)) - (combine v - ((car-p (car v)) neg-party) - ((cdr-p (cdr v)) neg-party)))))) + (define car-p (car-late-neg-proj (blame-add-car-context blame))) + (define cdr-p (cdr-late-neg-proj (blame-add-cdr-context blame))) + (λ (v neg-party) + (unless (pair? v) + (raise-not-cons-blame-error blame #:missing-party neg-party v)) + (combine v + (car-p (car v) neg-party) + (cdr-p (cdr v) neg-party))))) (define ((cons/c-ho-check combine) ctc) (define ctc-car (the-cons/c-hd-ctc ctc)) @@ -959,7 +955,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:flat-contract (build-flat-contract-property - #:val-first-projection (cons/c-val-first-ho-check (λ (v a d) v)) + #:late-neg-projection (cons/c-late-neg-ho-check (λ (v a d) v)) #:projection (cons/c-ho-check (λ (v a d) v)) #:name cons/c-name #:first-order cons/c-first-order @@ -971,7 +967,7 @@ #:property prop:chaperone-contract (parameterize ([skip-projection-wrapper? #t]) (build-chaperone-contract-property - #:val-first-projection (cons/c-val-first-ho-check (λ (v a d) (cons a d))) + #:late-neg-projection (cons/c-late-neg-ho-check (λ (v a d) (cons a d))) #:projection (cons/c-ho-check (λ (v a d) (cons a d))) #:name cons/c-name #:first-order cons/c-first-order @@ -982,7 +978,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:val-first-projection (cons/c-val-first-ho-check (λ (v a d) (cons a d))) + #:late-neg-projection (cons/c-late-neg-ho-check (λ (v a d) (cons a d))) #:projection (cons/c-ho-check (λ (v a d) (cons a d))) #:name cons/c-name #:first-order cons/c-first-order @@ -1001,8 +997,8 @@ [else (impersonator-cons/c ctc-car ctc-cdr)])) -(define (cons/dc-val-first-projection ctc) - (define undep-proj (get/build-val-first-projection (the-cons/dc-undep ctc))) +(define (cons/dc-late-neg-projection ctc) + (define undep-proj (get/build-late-neg-projection (the-cons/dc-undep ctc))) (define dep-proc (the-cons/dc-dep ctc)) (define forwards? (the-cons/dc-forwards? ctc)) (λ (blame) @@ -1013,28 +1009,26 @@ (undep-proj (blame-replace-negative (if forwards? cdr-blame car-blame) (the-cons/dc-here ctc)))) - (λ (val) + (λ (val neg-party) (cond [(pair? val) - (λ (neg-party) - (define-values (orig-undep orig-dep) - (if forwards? - (values (car val) (cdr val)) - (values (cdr val) (car val)))) - (define new-undep ((undep-proj+blame orig-undep) neg-party)) - (define new-dep-ctc (coerce-contract - 'cons/dc - (dep-proc ((undep-proj+indy-blame orig-undep) neg-party)))) - (define new-dep ((((get/build-val-first-projection new-dep-ctc) - (if forwards? cdr-blame car-blame)) - orig-dep) - neg-party)) + (define-values (orig-undep orig-dep) (if forwards? - (cons new-undep new-dep) - (cons new-dep new-undep)))] + (values (car val) (cdr val)) + (values (cdr val) (car val)))) + (define new-undep (undep-proj+blame orig-undep neg-party)) + (define new-dep-ctc (coerce-contract + 'cons/dc + (dep-proc (undep-proj+indy-blame orig-undep neg-party)))) + (define new-dep (((get/build-late-neg-projection new-dep-ctc) + (if forwards? cdr-blame car-blame)) + orig-dep + neg-party)) + (if forwards? + (cons new-undep new-dep) + (cons new-dep new-undep))] [else - (λ (neg-party) - (raise-not-cons-blame-error blame val #:missing-party neg-party))])))) + (raise-not-cons-blame-error blame val #:missing-party neg-party)])))) (define (cons/dc-name ctc) (define info (the-cons/dc-name-info ctc)) @@ -1079,7 +1073,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:flat-contract (build-flat-contract-property - #:val-first-projection cons/dc-val-first-projection + #:late-neg-projection cons/dc-late-neg-projection #:name cons/dc-name #:first-order cons/dc-first-order #:stronger cons/dc-stronger? @@ -1089,7 +1083,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:val-first-projection cons/dc-val-first-projection + #:late-neg-projection cons/dc-late-neg-projection #:name cons/dc-name #:first-order cons/dc-first-order #:stronger cons/dc-stronger? @@ -1099,7 +1093,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:val-first-projection cons/dc-val-first-projection + #:late-neg-projection cons/dc-late-neg-projection #:name cons/dc-name #:first-order cons/dc-first-order #:stronger cons/dc-stronger? @@ -1240,37 +1234,34 @@ #:generate list/c-generate #:exercise list/c-exercise #:stronger list/c-stronger - #:val-first-projection + #:late-neg-projection (λ (c) - (λ (blame) + (λ (blame) (define projs (for/list ([ctc (in-list (generic-list/c-args c))] [i (in-naturals 1)]) - ((get/build-val-first-projection ctc) + ((get/build-late-neg-projection ctc) (add-list-context blame i)))) - (define expected-length (length (generic-list/c-args c))) - (λ (val) + (define args (generic-list/c-args c)) + (define expected-length (length args)) + (λ (val neg-party) (cond [(list? val) - (define args (generic-list/c-args c)) (define actual-length (length val)) (cond [(= actual-length expected-length) - (λ (neg-party) - (for ([proj (in-list projs)] - [ele (in-list val)]) - ((proj ele) neg-party)) - val)] + (for ([proj (in-list projs)] + [ele (in-list val)]) + (proj ele neg-party)) + val] [else - (λ (neg-party) - (expected-a-list-of-len val actual-length expected-length blame - #:missing-party neg-party))])] + (expected-a-list-of-len val actual-length expected-length blame + #:missing-party neg-party)])] [else - (λ (neg-party) - (raise-blame-error blame #:missing-party neg-party - val - '(expected "a list" given: "~e") - val))])))) + (raise-blame-error blame #:missing-party neg-party + val + '(expected "a list" given: "~e") + val)])))) #:projection (lambda (c) (lambda (blame) @@ -1327,30 +1318,27 @@ (if (= actual 1) "" "s") x)]))) -(define (list/c-chaperone/other-val-first-projection c) - (define projs (map get/build-val-first-projection (generic-list/c-args c))) +(define (list/c-chaperone/other-late-neg-projection c) + (define projs (map get/build-late-neg-projection (generic-list/c-args c))) (define expected (length projs)) (λ (blame) (define p-apps (for/list ([proj (in-list projs)] [i (in-naturals 1)]) (proj (add-list-context blame i)))) - (λ (val) + (λ (val neg-party) (cond [(list? val) (define actual (length val)) (cond [(= actual expected) - (λ (neg-party) - (for/list ([item (in-list val)] - [p-app (in-list p-apps)]) - ((p-app item) neg-party)))] + (for/list ([item (in-list val)] + [p-app (in-list p-apps)]) + (p-app item neg-party))] [else - (λ (neg-party) - (expected-a-list-of-len val actual expected blame - #:missing-party neg-party))])] + (expected-a-list-of-len val actual expected blame + #:missing-party neg-party)])] [else - (λ (neg-party) - (expected-a-list val blame #:missing-party neg-party))])))) + (expected-a-list val blame #:missing-party neg-party)])))) (define (add-list-context blame i) (blame-add-context blame (format "the ~a~a element of" @@ -1372,7 +1360,7 @@ #:exercise list/c-exercise #:stronger list/c-stronger #:projection list/c-chaperone/other-projection - #:val-first-projection list/c-chaperone/other-val-first-projection + #:late-neg-projection list/c-chaperone/other-late-neg-projection #:list-contract? (λ (c) #t)))) (struct higher-order-list/c generic-list/c () @@ -1385,7 +1373,7 @@ #:exercise list/c-exercise #:stronger list/c-stronger #:projection list/c-chaperone/other-projection - #:val-first-projection list/c-chaperone/other-val-first-projection + #:late-neg-projection list/c-chaperone/other-late-neg-projection #:list-contract? (λ (c) #t))) (struct syntax-ctc (ctc) @@ -1416,30 +1404,28 @@ [else (promise-ctc ctc)]))) -(define (promise-contract-val-first-proj ctc) +(define (promise-contract-late-neg-proj ctc) (define chap? (chaperone-promise-ctc? ctc)) (define c/i-struct (if chap? chaperone-struct impersonate-struct)) (define c/i-procedure (if chap? chaperone-procedure impersonate-procedure)) - (define ctc-proc (get/build-val-first-projection (promise-base-ctc-ctc ctc))) + (define ctc-proc (get/build-late-neg-projection (promise-base-ctc-ctc ctc))) (λ (blame) (define p-app (ctc-proc (blame-add-context blame "the promise from"))) - (λ (val) + (λ (val neg-party) (if (promise? val) - (λ (neg-party) - (c/i-struct - val - promise-forcer - (λ (_ proc) - (c/i-procedure - proc - (λ (promise) - (values (λ (val) ((p-app val) neg-party)) promise)))))) - (λ (neg-party) - (raise-blame-error - blame #:missing-party neg-party - val - '(expected: "" given: "~e") - val)))))) + (c/i-struct + val + promise-forcer + (λ (_ proc) + (c/i-procedure + proc + (λ (promise) + (values (λ (val) (p-app val neg-party)) promise))))) + (raise-blame-error + blame #:missing-party neg-party + val + '(expected: "" given: "~e") + val))))) (define (promise-contract-name ctc) (build-compound-type-name 'promise/c (promise-base-ctc-ctc ctc))) @@ -1455,7 +1441,7 @@ #:property prop:chaperone-contract (build-chaperone-contract-property #:name promise-contract-name - #:val-first-projection promise-contract-val-first-proj + #:late-neg-projection promise-contract-late-neg-proj #:stronger promise-ctc-stronger? #:first-order (λ (ctc) promise?))) (struct promise-ctc promise-base-ctc () @@ -1463,7 +1449,7 @@ #:property prop:contract (build-contract-property #:name promise-contract-name - #:val-first-projection promise-contract-val-first-proj + #:late-neg-projection promise-contract-late-neg-proj #:stronger promise-ctc-stronger? #:first-order (λ (ctc) promise?))) @@ -1509,31 +1495,29 @@ partial-pos-contract)] [else (raise-blame-error blame val '(expected "a parameter"))]))))) - #:val-first-projection + #:late-neg-projection (λ (ctc) - (define in-proc (contract-projection (parameter/c-in ctc))) - (define out-proc (contract-projection (parameter/c-out ctc))) + (define in-proc (get/build-late-neg-projection (parameter/c-in ctc))) + (define out-proc (get/build-late-neg-projection (parameter/c-out ctc))) (λ (blame) (define blame/c (blame-add-context blame "the parameter of")) - (define swapped (blame-swap blame/c)) - (λ (val) + (define in-proj (in-proc (blame-swap blame/c))) + (define out-proj (out-proc blame/c)) + (λ (val neg-party) (cond [(parameter? val) - (λ (neg-party) - (define (add-profiling f) - (λ (x) - (with-continuation-mark contract-continuation-mark-key - (cons blame neg-party) - (f x)))) - (make-derived-parameter - val - ;; unfortunately expensive - (add-profiling (in-proc (blame-add-missing-party swapped neg-party))) - (add-profiling (out-proc (blame-add-missing-party blame/c neg-party)))))] + (define (add-profiling f) + (λ (x) + (with-continuation-mark contract-continuation-mark-key + (cons blame/c neg-party) + (f x neg-party)))) + (make-derived-parameter + val + (add-profiling in-proj) + (add-profiling out-proj))] [else - (λ (neg-party) - (raise-blame-error blame #:missing-party neg-party - val '(expected "a parameter")))])))) + (raise-blame-error blame #:missing-party neg-party + val '(expected "a parameter"))])))) #:name (λ (ctc) (apply build-compound-type-name @@ -1584,7 +1568,7 @@ (define (get-any? c) any?) (define (any? x) #t) -(define any/c-neg-party-fn (λ (val) (λ (neg-party) val))) +(define any/c-neg-party-fn (λ (val neg-party) val)) (define (random-any/c env fuel) (define env-hash (contract-random-generate-env-hash env)) @@ -1624,7 +1608,7 @@ #:property prop:flat-contract (build-flat-contract-property #:projection get-any-projection - #:val-first-projection (λ (ctc) (λ (blame) any/c-neg-party-fn)) + #:late-neg-projection (λ (ctc) (λ (blame) any/c-neg-party-fn)) #:stronger (λ (this that) (any/c? that)) #:name (λ (ctc) 'any/c) #:generate (λ (ctc) @@ -1648,7 +1632,7 @@ (none/c-name ctc) val)))) -(define ((((none-curried-val-first-proj ctc) blame) val) neg-party) +(define (((none-curried-late-neg-proj ctc) blame) val neg-party) (raise-blame-error blame #:missing-party neg-party val @@ -1662,7 +1646,7 @@ #:property prop:flat-contract (build-flat-contract-property #:projection none-curried-proj - #:val-first-projection none-curried-val-first-proj + #:late-neg-projection none-curried-late-neg-proj #:stronger (λ (this that) #t) #:name (λ (ctc) (none/c-name ctc)) #:first-order (λ (ctc) (λ (val) #f)))) @@ -1731,52 +1715,51 @@ impersonator-prop:contracted ctc impersonator-prop:blame blame)))) -(define ((prompt-tag/c-val-first-proj chaperone?) ctc) +(define ((prompt-tag/c-late-neg-proj chaperone?) ctc) (define proxy (if chaperone? chaperone-prompt-tag impersonate-prompt-tag)) (define proc-proxy (if chaperone? chaperone-procedure impersonate-procedure)) (define ho-projs - (map get/build-val-first-projection (base-prompt-tag/c-ctcs ctc))) + (map get/build-late-neg-projection (base-prompt-tag/c-ctcs ctc))) (define call/cc-projs - (map get/build-val-first-projection (base-prompt-tag/c-call/ccs ctc))) + (map get/build-late-neg-projection (base-prompt-tag/c-call/ccs ctc))) (λ (blame) (define swapped (blame-swap blame)) (define ho-neg-projs (for/list ([proj (in-list ho-projs)]) (proj swapped))) (define ho-pos-projs (for/list ([proj (in-list ho-projs)]) (proj blame))) (define cc-neg-projs (for/list ([proj (in-list call/cc-projs)]) (proj swapped))) (define cc-pos-projs (for/list ([proj (in-list call/cc-projs)]) (proj blame))) - (λ (val) - (define (make-proj projs neg-party) - (λ vs - (define vs2 (for/list ([proj projs] [v vs]) - ((proj v) neg-party))) - (apply values vs2))) + (define (make-proj projs neg-party) + (λ vs + (apply values + (for/list ([proj (in-list projs)] + [v (in-list vs)]) + (proj v neg-party))))) + (λ (val neg-party) ;; now do the actual wrapping (cond [(continuation-prompt-tag? val) - (λ (neg-party) - ;; prompt/abort projections - (define proj1 (make-proj ho-pos-projs neg-party)) - (define proj2 (make-proj ho-neg-projs neg-party)) - ;; call/cc projections - (define call/cc-guard (make-proj cc-pos-projs neg-party)) - (define call/cc-proxy - (λ (f) - (proc-proxy - f - (λ args - (apply values (make-proj cc-neg-projs neg-party) args))))) - (proxy val - proj1 proj2 - call/cc-guard call/cc-proxy - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party blame neg-party)))] + ;; prompt/abort projections + (define proj1 (make-proj ho-pos-projs neg-party)) + (define proj2 (make-proj ho-neg-projs neg-party)) + ;; call/cc projections + (define call/cc-guard (make-proj cc-pos-projs neg-party)) + (define call/cc-proxy + (λ (f) + (proc-proxy + f + (λ args + (apply values (make-proj cc-neg-projs neg-party) args))))) + (proxy val + proj1 proj2 + call/cc-guard call/cc-proxy + impersonator-prop:contracted ctc + impersonator-prop:blame (blame-add-missing-party blame neg-party))] [else - (λ (neg-party) - (raise-blame-error - blame #:missing-party neg-party val - '(expected: "~s" given: "~e") - (contract-name ctc) - val))])))) + (raise-blame-error + blame #:missing-party neg-party val + '(expected: "~s" given: "~e") + (contract-name ctc) + val)])))) (define (prompt-tag/c-stronger? this that) (and (base-prompt-tag/c? that) @@ -1794,7 +1777,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:val-first-projection (prompt-tag/c-val-first-proj #t) + #:late-neg-projection (prompt-tag/c-late-neg-proj #t) #:projection (prompt-tag/c-proj #t) #:first-order (λ (ctc) continuation-prompt-tag?) #:stronger prompt-tag/c-stronger? @@ -1804,7 +1787,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:val-first-projection (prompt-tag/c-val-first-proj #f) + #:late-neg-projection (prompt-tag/c-late-neg-proj #f) #:projection (prompt-tag/c-proj #f) #:first-order (λ (ctc) continuation-prompt-tag?) #:stronger prompt-tag/c-stronger? @@ -1841,31 +1824,29 @@ impersonator-prop:contracted ctc impersonator-prop:blame blame)))) -(define ((continuation-mark-key/c-val-first-proj proxy) ctc) +(define ((continuation-mark-key/c-late-neg-proj proxy) ctc) (define ho-proj - (get/build-val-first-projection (base-continuation-mark-key/c-ctc ctc))) + (get/build-late-neg-projection (base-continuation-mark-key/c-ctc ctc))) (λ (blame) (define swapped (blame-swap blame)) (define proj1 (ho-proj blame)) (define proj2 (ho-proj (blame-swap blame))) - (λ (val) + (λ (val neg-party) (cond [(continuation-mark-key? val) - (λ (neg-party) - (proxy val - (λ (v) ((proj1 v) neg-party)) - (λ (v) ((proj2 v) neg-party)) - impersonator-prop:contracted ctc - impersonator-prop:blame blame))] + (proxy val + (λ (v) (proj1 v neg-party)) + (λ (v) (proj2 v neg-party)) + impersonator-prop:contracted ctc + impersonator-prop:blame blame)] [else - (λ (neg-party) - (unless (contract-first-order-passes? ctc val) - (raise-blame-error - blame #:missing-party neg-party - val - '(expected: "~s" given: "~e") - (contract-name ctc) - val)))])))) + (unless (contract-first-order-passes? ctc val) + (raise-blame-error + blame #:missing-party neg-party + val + '(expected: "~s" given: "~e") + (contract-name ctc) + val))])))) (define (continuation-mark-key/c-stronger? this that) (and (base-continuation-mark-key/c? that) @@ -1881,7 +1862,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:val-first-projection (continuation-mark-key/c-val-first-proj chaperone-continuation-mark-key) + #:late-neg-projection (continuation-mark-key/c-late-neg-proj chaperone-continuation-mark-key) #:projection (continuation-mark-key/c-proj chaperone-continuation-mark-key) #:first-order (λ (ctc) continuation-mark-key?) #:stronger continuation-mark-key/c-stronger? @@ -1893,7 +1874,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:val-first-projection (continuation-mark-key/c-val-first-proj impersonate-continuation-mark-key) + #:late-neg-projection (continuation-mark-key/c-late-neg-proj impersonate-continuation-mark-key) #:projection (continuation-mark-key/c-proj impersonate-continuation-mark-key) #:first-order (λ (ctc) continuation-mark-key?) #:stronger continuation-mark-key/c-stronger? @@ -1995,30 +1976,28 @@ impersonator-prop:contracted ctc impersonator-prop:blame blame)))) -(define ((channel/c-val-first-proj proxy) ctc) +(define ((channel/c-late-neg-proj proxy) ctc) (define ho-proj - (get/build-val-first-projection (base-channel/c-ctc ctc))) + (get/build-late-neg-projection (base-channel/c-ctc ctc))) (λ (blame) (define pos-proj (ho-proj blame)) (define neg-proj (ho-proj (blame-swap blame))) - (define (proj1 neg-party) (λ (ch) (values ch (λ (v) ((pos-proj v) neg-party))))) - (define (proj2 neg-party) (λ (ch v) ((neg-proj v) neg-party))) - (λ (val) + (define (proj1 neg-party) (λ (ch) (values ch (λ (v) (pos-proj v neg-party))))) + (define (proj2 neg-party) (λ (ch v) (neg-proj v neg-party))) + (λ (val neg-party) (cond [(channel? val) - (λ (neg-party) - (proxy val - (proj1 neg-party) - (proj2 neg-party) - impersonator-prop:contracted ctc - impersonator-prop:blame blame))] + (proxy val + (proj1 neg-party) + (proj2 neg-party) + impersonator-prop:contracted ctc + impersonator-prop:blame blame)] [else - (λ (neg-party) - (raise-blame-error - blame #:missing-party neg-party - val '(expected: "~s" given: "~e") - (contract-name ctc) - val))])))) + (raise-blame-error + blame #:missing-party neg-party + val '(expected: "~s" given: "~e") + (contract-name ctc) + val)])))) (define (channel/c-first-order ctc) channel?) @@ -2035,7 +2014,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract (build-chaperone-contract-property - #:val-first-projection (channel/c-val-first-proj chaperone-channel) + #:late-neg-projection (channel/c-late-neg-proj chaperone-channel) #:projection (channel/c-proj chaperone-channel) #:first-order channel/c-first-order #:stronger channel/c-stronger? @@ -2046,7 +2025,7 @@ #:property prop:custom-write custom-write-property-proc #:property prop:contract (build-contract-property - #:val-first-projection (channel/c-val-first-proj impersonate-channel) + #:late-neg-projection (channel/c-late-neg-proj impersonate-channel) #:projection (channel/c-proj impersonate-channel) #:first-order channel/c-first-order #:stronger channel/c-stronger? @@ -2086,6 +2065,9 @@ (define (contract-val-first-projection ctc) (contract-struct-val-first-projection (coerce-contract 'contract-projection ctc))) +(define (contract-late-neg-projection ctc) + (contract-struct-late-neg-projection + (coerce-contract 'contract-projection ctc))) (define (get/build-val-first-projection ctc) (or (contract-struct-val-first-projection ctc) @@ -2097,6 +2079,14 @@ ((p (blame-add-missing-party blme neg-party)) val))) (string->symbol (format "val-first: ~s" (contract-name ctc)))))))) +(define (get/build-late-neg-projection ctc) + (or (contract-struct-late-neg-projection ctc) + (let ([p (contract-projection ctc)]) + (λ (blme) + (procedure-rename + (λ (val neg-party) + ((p (blame-add-missing-party blme neg-party)) val)) + (string->symbol (format "late-neg: ~s" (contract-name ctc)))))))) (define (flat-contract predicate) (coerce-flat-contract 'flat-contract predicate)) (define (flat-named-contract name pre-contract [generate #f]) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index 63f5ed95a6..d1ee02c67f 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -68,15 +68,15 @@ [(pred val) val] [else (partial-contract val)]))))) -(define (single-or/c-val-first-projection ctc) - (define c-proj (get/build-val-first-projection (single-or/c-ho-ctc ctc))) +(define (single-or/c-late-neg-projection ctc) + (define c-proj (get/build-late-neg-projection (single-or/c-ho-ctc ctc))) (define pred (single-or/c-pred ctc)) (λ (blame) (define p-app (c-proj (blame-add-or-context blame))) - (λ (val) + (λ (val neg-party) (if (pred val) - (λ (neg-party) val) - (p-app val))))) + val + (p-app val neg-party))))) (define (blame-add-or-context blame) (blame-add-context blame "a part of the or/c of")) @@ -200,7 +200,7 @@ (parameterize ([skip-projection-wrapper? #t]) (build-chaperone-contract-property #:projection single-or/c-projection - #:val-first-projection single-or/c-val-first-projection + #:late-neg-projection single-or/c-late-neg-projection #:name single-or/c-name #:first-order single-or/c-first-order #:stronger single-or/c-stronger? @@ -215,7 +215,7 @@ #:property prop:contract (build-contract-property #:projection single-or/c-projection - #:val-first-projection single-or/c-val-first-projection + #:late-neg-projection single-or/c-late-neg-projection #:name single-or/c-name #:first-order single-or/c-first-order #:stronger single-or/c-stronger? @@ -273,21 +273,22 @@ candidate-proc candidate-contract)]))]))))) -(define (multi-or/c-val-first-proj ctc) +(define (multi-or/c-late-neg-proj ctc) (define ho-contracts (multi-or/c-ho-ctcs ctc)) - (define c-projs (map get/build-val-first-projection ho-contracts)) + (define c-projs (map get/build-late-neg-projection ho-contracts)) (define first-order-checks (map (λ (x) (contract-first-order x)) ho-contracts)) (define predicates (map flat-contract-predicate (multi-or/c-flat-ctcs ctc))) (λ (blame) (define blame-w-context (blame-add-or-context blame)) - (λ (val) + (define c-projs+blame (map (λ (c-proj) (c-proj blame-w-context)) c-projs)) + (λ (val neg-party) (cond [(for/or ([pred (in-list predicates)]) (pred val)) - (λ (neg-party) val)] + val] [else (let loop ([checks first-order-checks] - [c-projs c-projs] + [c-projs c-projs+blame] [contracts ho-contracts] [candidate-c-proj #f] [candidate-contract #f]) @@ -295,22 +296,20 @@ [(null? checks) (cond [candidate-c-proj - ((candidate-c-proj blame-w-context) val)] + (candidate-c-proj val neg-party)] [else - (λ (neg-party) - (raise-blame-error blame val #:missing-party neg-party - '("none of the branches of the or/c matched" given: "~e") - val))])] + (raise-blame-error blame val #:missing-party neg-party + '("none of the branches of the or/c matched" given: "~e") + val)])] [((car checks) val) (if candidate-c-proj - (λ (neg-party) - (raise-blame-error blame val #:missing-party neg-party - '("two of the clauses in the or/c might both match: ~s and ~s" - given: - "~e") - (contract-name candidate-contract) - (contract-name (car contracts)) - val)) + (raise-blame-error blame val #:missing-party neg-party + '("two of the clauses in the or/c might both match: ~s and ~s" + given: + "~e") + (contract-name candidate-contract) + (contract-name (car contracts)) + val) (loop (cdr checks) (cdr c-projs) (cdr contracts) @@ -359,7 +358,7 @@ (parameterize ([skip-projection-wrapper? #t]) (build-chaperone-contract-property #:projection multi-or/c-proj - #:val-first-projection multi-or/c-val-first-proj + #:late-neg-projection multi-or/c-late-neg-proj #:name multi-or/c-name #:first-order multi-or/c-first-order #:stronger multi-or/c-stronger? @@ -374,7 +373,7 @@ #:property prop:contract (build-contract-property #:projection multi-or/c-proj - #:val-first-projection multi-or/c-val-first-proj + #:late-neg-projection multi-or/c-late-neg-proj #:name multi-or/c-name #:first-order multi-or/c-first-order #:stronger multi-or/c-stronger? diff --git a/racket/collects/racket/contract/private/prop.rkt b/racket/collects/racket/contract/private/prop.rkt index 5262383059..cadcc3074d 100644 --- a/racket/collects/racket/contract/private/prop.rkt +++ b/racket/collects/racket/contract/private/prop.rkt @@ -10,6 +10,7 @@ contract-struct-first-order contract-struct-projection contract-struct-val-first-projection + contract-struct-late-neg-projection contract-struct-stronger? contract-struct-generate contract-struct-exercise @@ -66,6 +67,7 @@ generate exercise val-first-projection + late-neg-projection list-contract? ] #:omit-define-syntaxes) @@ -106,6 +108,12 @@ (and get-projection (get-projection c))) +(define (contract-struct-late-neg-projection c) + (define prop (contract-struct-property c)) + (define get-projection (contract-property-late-neg-projection prop)) + (and get-projection + (get-projection c))) + (define trail (make-parameter #f)) (define (contract-struct-stronger? a b) (define prop (contract-struct-property a)) @@ -255,6 +263,7 @@ #:first-order [get-first-order #f] #:projection [get-projection #f] #:val-first-projection [get-val-first-projection #f] + #:late-neg-projection [get-late-neg-projection #f] #:stronger [stronger #f] #:generate [generate (λ (ctc) (λ (fuel) #f))] #:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))] @@ -289,7 +298,8 @@ (mk get-name get-first-order get-projection stronger generate exercise - get-val-first-projection + get-val-first-projection + get-late-neg-projection list-contract?))) (define build-contract-property @@ -372,7 +382,8 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-struct make-contract [ name first-order projection val-first-projection +(define-struct make-contract [ name first-order projection + val-first-projection late-neg-projection stronger generate exercise list-contract? ] #:omit-define-syntaxes #:property prop:custom-write @@ -386,12 +397,14 @@ #:first-order (lambda (c) (make-contract-first-order c)) #:projection (lambda (c) (make-contract-projection c)) #:val-first-projection (lambda (c) (make-contract-val-first-projection c)) + #:late-neg-projection (lambda (c) (make-contract-late-neg-projection c)) #:stronger (lambda (a b) ((make-contract-stronger a) a b)) #:generate (lambda (c) (make-contract-generate c)) #:exercise (lambda (c) (make-contract-exercise c)) #:list-contract? (λ (c) (make-contract-list-contract? c)))) -(define-struct make-chaperone-contract [ name first-order projection val-first-projection +(define-struct make-chaperone-contract [ name first-order projection + val-first-projection late-neg-projection stronger generate exercise list-contract? ] #:omit-define-syntaxes #:property prop:custom-write @@ -405,12 +418,14 @@ #:first-order (lambda (c) (make-chaperone-contract-first-order c)) #:projection (lambda (c) (make-chaperone-contract-projection c)) #:val-first-projection (lambda (c) (make-chaperone-contract-val-first-projection c)) + #:late-neg-projection (lambda (c) (make-chaperone-contract-late-neg-projection c)) #:stronger (lambda (a b) ((make-chaperone-contract-stronger a) a b)) #:generate (lambda (c) (make-chaperone-contract-generate c)) #:exercise (lambda (c) (make-chaperone-contract-exercise c)) #:list-contract? (λ (c) (make-chaperone-contract-list-contract? c)))) -(define-struct make-flat-contract [ name first-order projection val-first-projection +(define-struct make-flat-contract [ name first-order projection + val-first-projection late-neg-projection stronger generate exercise list-contract? ] #:omit-define-syntaxes #:property prop:custom-write @@ -423,6 +438,7 @@ #:name (lambda (c) (make-flat-contract-name c)) #:first-order (lambda (c) (make-flat-contract-first-order c)) #:val-first-projection (λ (c) (make-flat-contract-val-first-projection c)) + #:late-neg-projection (λ (c) (make-flat-contract-late-neg-projection c)) #:projection (lambda (c) (make-flat-contract-projection c)) #:stronger (lambda (a b) ((make-flat-contract-stronger a) a b)) #:generate (lambda (c) (make-flat-contract-generate c)) @@ -434,6 +450,7 @@ #:first-order [first-order #f] #:projection [projection #f] #:val-first-projection [val-first-projection #f] + #:late-neg-projection [late-neg-projection #f] #:stronger [stronger #f] #:generate [generate (λ (ctc) (λ (fuel) #f))] #:exercise [exercise (λ (ctc) (λ (fuel) (values void '())))] @@ -448,7 +465,7 @@ [stronger (or stronger as-strong?)]) (mk name first-order - projection val-first-projection + projection val-first-projection late-neg-projection stronger generate exercise list-contract?))) diff --git a/racket/collects/racket/contract/private/vector.rkt b/racket/collects/racket/contract/private/vector.rkt index 8074870d61..f5db23de87 100644 --- a/racket/collects/racket/contract/private/vector.rkt +++ b/racket/collects/racket/contract/private/vector.rkt @@ -68,9 +68,9 @@ (fail val '(expected: "~s for element ~s" given: "~e") (contract-name elem-ctc) n e)))) #t))) -(define (check-val-first-vectorof c) +(define (check-late-neg-vectorof c) (define immutable (base-vectorof-immutable c)) - (λ (val blame) + (λ (val blame neg-party) (cond [(vector? val) (cond @@ -78,23 +78,20 @@ (cond [(immutable? val) #f] [else - (λ (neg-party) - (raise-blame-error blame #:missing-party neg-party - val '(expected "an immutable vector" given: "~e") val))])] + (raise-blame-error blame #:missing-party neg-party + val '(expected "an immutable vector" given: "~e") val)])] [(eq? immutable #f) (cond [(immutable? val) - (λ (neg-party) - (raise-blame-error blame #:missing-party neg-party - val '(expected "an mutable vector" given: "~e" val)))] + (raise-blame-error blame #:missing-party neg-party + val '(expected "an mutable vector" given: "~e" val))] [else #f])] [else #f])] [else - (λ (neg-party) - (raise-blame-error blame #:missing-party neg-party - val - '(expected "a vector," given: "~e") - val))]))) + (raise-blame-error blame #:missing-party neg-party + val + '(expected "a vector," given: "~e") + val)]))) (define (vectorof-first-order ctc) (let ([check (check-vectorof ctc)]) @@ -126,29 +123,28 @@ (build-flat-contract-property #:name vectorof-name #:first-order vectorof-first-order - #:val-first-projection (λ (ctc) - (define check (check-val-first-vectorof ctc)) - (define vfp (get/build-val-first-projection (base-vectorof-elem ctc))) - (λ (blame) - (define ele-blame (blame-add-element-of-context blame)) - (define vfp+blame (vfp ele-blame)) - (λ (val) - (or (check val blame) - (λ (neg-party) - (for ([x (in-vector val)]) - ((vfp+blame x) neg-party)) - val))))) + #:late-neg-projection (λ (ctc) + (define check (check-late-neg-vectorof ctc)) + (define vfp (get/build-late-neg-projection (base-vectorof-elem ctc))) + (λ (blame) + (define ele-blame (blame-add-element-of-context blame)) + (define vfp+blame (vfp ele-blame)) + (λ (val neg-party) + (check val blame neg-party) + (for ([x (in-vector val)]) + (vfp+blame x neg-party)) + val))) #:stronger vectorof-stronger #:projection (λ (ctc) (define check (check-vectorof ctc)) (λ (blame) - (define raise-blame (λ (val . args) - (apply raise-blame-error blame val args))) + (define raise-blame (λ (val . args) (apply raise-blame-error blame val args))) + (define ele-blame (blame-add-element-of-context blame)) (λ (val) (check val raise-blame #f) (let* ([elem-ctc (base-vectorof-elem ctc)] - [p ((contract-projection elem-ctc) blame)]) + [p ((contract-projection elem-ctc) ele-blame)]) (for ([e (in-vector val)]) (p e))) val))))) @@ -156,7 +152,7 @@ (define (blame-add-element-of-context blame #:swap? [swap? #f]) (blame-add-context blame "an element of" #:swap? swap?)) -(define (vectorof-val-first-ho-projection chaperone-or-impersonate-vector) +(define (vectorof-late-neg-ho-projection chaperone-or-impersonate-vector) (λ (ctc) (define elem-ctc (base-vectorof-elem ctc)) (define immutable (base-vectorof-immutable ctc)) @@ -164,40 +160,34 @@ (λ (blame) (define pos-blame (blame-add-element-of-context blame)) (define neg-blame (blame-add-element-of-context blame #:swap? #t)) - (define vfp (get/build-val-first-projection elem-ctc)) + (define vfp (get/build-late-neg-projection elem-ctc)) (define elem-pos-proj (vfp pos-blame)) (define elem-neg-proj (vfp neg-blame)) (define checked-ref (λ (neg-party) (λ (vec i val) - (with-continuation-mark - contract-continuation-mark-key - (cons pos-blame neg-party) - ((elem-pos-proj val) neg-party))))) + (with-continuation-mark contract-continuation-mark-key + (cons pos-blame neg-party) + (elem-pos-proj val neg-party))))) (define checked-set (λ (neg-party) (λ (vec i val) - (with-continuation-mark - contract-continuation-mark-key - (cons neg-blame neg-party) - ((elem-neg-proj val) neg-party))))) + (with-continuation-mark contract-continuation-mark-key + (cons neg-blame neg-party) + (elem-neg-proj val neg-party))))) - (λ (val) - (let/ec k - (define (raise-blame val . args) - (k - (λ (neg-party) - (apply raise-blame-error blame #:missing-party neg-party val args)))) - (check val raise-blame #f) - (λ (neg-party) - (if (and (immutable? val) (not (chaperone? val))) - (apply vector-immutable - (for/list ([e (in-vector val)]) - ((elem-pos-proj e) neg-party))) - (chaperone-or-impersonate-vector - val - (checked-ref neg-party) - (checked-set neg-party) - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party blame neg-party))))))))) + (λ (val neg-party) + (define (raise-blame val . args) + (apply raise-blame-error blame #:missing-party neg-party val args)) + (check val raise-blame #f) + (if (and (immutable? val) (not (chaperone? val))) + (apply vector-immutable + (for/list ([e (in-vector val)]) + (elem-pos-proj e neg-party))) + (chaperone-or-impersonate-vector + val + (checked-ref neg-party) + (checked-set neg-party) + impersonator-prop:contracted ctc + impersonator-prop:blame (blame-add-missing-party blame neg-party))))))) (define-values (prop:neg-blame-party prop:neg-blame-party? prop:neg-blame-party-get) (make-impersonator-property 'prop:neg-blame-party)) @@ -242,7 +232,7 @@ #:name vectorof-name #:first-order vectorof-first-order #:stronger vectorof-stronger - #:val-first-projection (vectorof-val-first-ho-projection chaperone-vector) + #:late-neg-projection (vectorof-late-neg-ho-projection chaperone-vector) #:projection (vectorof-ho-projection chaperone-vector))) (define-struct (impersonator-vectorof base-vectorof) () @@ -252,7 +242,7 @@ #:name vectorof-name #:first-order vectorof-first-order #:stronger vectorof-stronger - #:val-first-projection (vectorof-val-first-ho-projection chaperone-vector) + #:late-neg-projection (vectorof-late-neg-ho-projection chaperone-vector) #:projection (vectorof-ho-projection impersonate-vector))) (define-syntax (wrap-vectorof stx) From 450ea8236d47ef652e48308c2561137c03207c70 Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Tue, 25 Aug 2015 21:13:42 -0500 Subject: [PATCH 133/381] Bug fix for calculating init-dependencies when subtyping is involved. --- racket/collects/racket/unit.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index a865dbbe9e..950dcf46c2 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -2181,8 +2181,8 @@ (for/or ([lr (in-list sub-in)]) (and (eq? (link-record-tag lr) (car dep)) - (free-identifier=? (link-record-sigid lr) - (cdr dep)) + (siginfo-subtype (signature-siginfo (lookup-signature (link-record-sigid lr))) + (signature-siginfo (lookup-signature (cdr dep)))) lr))) ;; If `lr` refers to an import, then propoagate the dependency. ;; If it refers to a linked unit, make sure that unit is earlier. From 4fefec63868064528ccb7dc081b47f5c314ff56c Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Mon, 31 Aug 2015 21:46:57 -0500 Subject: [PATCH 134/381] Add test case Closes PR 15139 --- pkgs/racket-test/tests/units/test-unit.rkt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkgs/racket-test/tests/units/test-unit.rkt b/pkgs/racket-test/tests/units/test-unit.rkt index 1d13a9b1fd..a3f04466e4 100644 --- a/pkgs/racket-test/tests/units/test-unit.rkt +++ b/pkgs/racket-test/tests/units/test-unit.rkt @@ -2199,3 +2199,16 @@ [(s x y) (list x y)])) S)))))) +;; Make sure init-dependencies are calculated correctly in the presence of subtyping +(let () + (define-signature a1^ (a1)) + (define-signature a2^ extends a1^ (a2)) + (define-unit u (import a1^) (export) (init-depend a1^) a1) + (define v + (compound-unit/infer + (import [A2 : a2^]) + (export) + (link (() u A2)))) + (define a1 1) + (define a2 2) + (test 1 (invoke-unit v (import a2^)))) From c290de0f88e4f31e56013fad4b9764d43d9a812e Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Tue, 1 Sep 2015 11:06:09 -0300 Subject: [PATCH 135/381] Fix typos --- racket/src/racket/src/eval.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 5fed396a50..43d7f6a6dc 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -62,7 +62,7 @@ When collecting the arguments for an application, scheme_do_eval() avoids recursive C calls to evaluate arguments by recognizing - easily-evaluated expressions, such as constrants and variable + easily-evaluated expressions, such as constants and variable lookups. This can be viewed as a kind of half-way A-normalization. Bytecodes are not linear. They're actually trees of expression @@ -81,7 +81,7 @@ Bytecode compilation: - Compilation works in four passes. + Compilation works in five passes. The first pass, called "compile", performs most of the work and tracks variable usage (including whether a variable is mutated or @@ -98,7 +98,7 @@ constant folding, and function inlining; this pass mutates records produced by the "letrec_check" pass. See "optimize.c". This pass isn't optional; for example, it calculates closure information that - the third pass uses. + the fourth pass uses. The fourth pass, called "resolve", finishes compilation by computing variable offsets and indirections (often mutating the records @@ -135,7 +135,7 @@ variants. The code is not actually JITted until it is called; this preparation step merely sets up a JIT hook for each function. The preparation pass is a shallow, function (i.e., it doesn't mutate - the original bytecode) pass; the body of a fuction is preparred for + the original bytecode) pass; the body of a function is prepared for JITting lazily. See "jitprep.c". */ From 929db29b67e80ac155868fca5e8823235a745b4e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 31 Aug 2015 20:21:40 -0600 Subject: [PATCH 136/381] add `prop:expansion-contexts` The `prop:expansion-contexts` property can control the expansion of a rename transformer in much the same that conditionals on `(syntax-local-context)` can control the expansion of other transformers. --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/stx-trans.scrbl | 42 + pkgs/racket-test-core/tests/racket/macro.rktl | 92 +- racket/src/racket/src/compile.c | 169 ++- racket/src/racket/src/cstartup.inc | 1322 ++++++++--------- racket/src/racket/src/eval.c | 29 +- racket/src/racket/src/schminc.h | 2 +- racket/src/racket/src/schpriv.h | 4 + racket/src/racket/src/schvers.h | 4 +- racket/src/racket/src/struct.c | 59 + 10 files changed, 1011 insertions(+), 714 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index cc51c43723..8d35324698 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.11") +(define version "6.2.900.12") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index b2a26def63..44278cc3a9 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -460,6 +460,48 @@ provided for backward compatibility; the more general @history[#:changed "6.3" @elem{Simplified the operation to @tech{scope} removal.}]} +@defthing[prop:expansion-contexts struct-type-property?]{ + +A @tech{structure type property} to constrain the use of macro +@tech{transformers} and @tech{rename transformers}. The property's +value must be a list of symbols, where the allowed symbols are +@racket['expression], @racket['top-level], @racket['module], +@racket['module-begin], and @racket['definition-context]. Each symbol +corresponds to an expansion context in the same way as for +@racket[local-expand] or as reported by @racket[syntax-local-context], +except that @racket['definition-context] is used (instead of a list) +to represent an @tech{internal-definition context}. + +If an identifier is bound to a transformer whose list does not include +a symbol for a particular use of the identifier, then the use is +adjusted as follows: +@; +@itemlist[ + + @item{In a @racket['module-begin] context, then the use is wrapped in + a @racket[begin] form.} + + @item{In a @racket['module], @racket['top-level], + @racket['internal-definition] or context, if + @racket['expression] is present in the list, then the use is + wrapped in an @racket[#%expression] form.} + + @item{Otherwise, a syntax error is reported.} + +] + +The @racket[prop:expansion-contexts] property is most useful in +combination with @racket[prop:rename-transformer], since a general +@tech{transformer} procedure can use @racket[syntax-local-context]. +Furthermore, a @racket[prop:expansion-contexts] property makes the +most sense when a @tech{rename transformer}'s identifier has the +@racket['not-free-identifier=?] property, otherwise a definition of +the binding creates a binding alias that effectively routes around the +@racket[prop:expansion-contexts] property. + +@history[#:added "6.2.900.12"]} + + @defproc[(syntax-local-value [id-stx syntax?] [failure-thunk (or/c (-> any) #f) #f] diff --git a/pkgs/racket-test-core/tests/racket/macro.rktl b/pkgs/racket-test-core/tests/racket/macro.rktl index 6f6192b9ce..dc0bc57b63 100644 --- a/pkgs/racket-test-core/tests/racket/macro.rktl +++ b/pkgs/racket-test-core/tests/racket/macro.rktl @@ -594,6 +594,97 @@ (test '(#t #f) (dynamic-require ''rename-transformer-tests:n 'go)) +;; ---------------------------------------- + +(let () + (define (go contexts + wrap + prop:macro + #:sub? [sub? #f] + #:trim-error [error-rx #f]) + (define o (open-output-bytes)) + (define e (open-output-bytes)) + (parameterize ([current-output-port o] + [current-error-port e] + [current-namespace (make-base-namespace)]) + (call-with-continuation-prompt + (lambda () + (eval + `(module m racket/base + (require (for-syntax racket/base)) + + (define v 0) + + (begin-for-syntax + (struct e (p) + #:property ,prop:macro ,(if (eq? prop:macro 'prop:procedure) + 0 + (list #'quote-syntax + (syntax-property #'v + 'not-free-identifier=? + #t))) + #:property prop:expansion-contexts ',contexts)) + + (define-syntax m (e (lambda (stx) + (displayln (syntax-local-context)) + #'10))) + + ,(wrap 'm))) + (dynamic-require (if sub? '(submod 'm sub) ''m) #f)))) + (list (get-output-string o) + (if error-rx + (let ([m (regexp-match error-rx (get-output-string e))]) + (or (and m (car m)) + (get-output-string e))) + (get-output-string e)))) + + (test '("module\n10\n" "") go '(module expression) list 'prop:procedure) + (test '("module\n10\n" "") go '(module expression) values 'prop:procedure) + (test '("expression\n10\n" "") go '(expression) list 'prop:procedure) + (test '("expression\n10\n" "") go '(expression) values 'prop:procedure) + (test '("" "m: not allowed in context\n expansion context: module") go '() values 'prop:procedure + #:trim-error #rx"^[^\n]*\n[^\n]*") + (test '("0\n" "") go '(module expression) values 'prop:rename-transformer) + (test '("" "application: not a procedure") go '(module expression) list 'prop:rename-transformer + #:trim-error #rx"^[^;]*") + (test '("0\n" "") go '(expression) values 'prop:rename-transformer) + (test '("" "application: not a procedure") go '(expression) list 'prop:rename-transformer + #:trim-error #rx"^[^;]*") + (test '("" "m: not allowed in context\n expansion context: module") go '() values 'prop:rename-transformer + #:trim-error #rx"^[^\n]*\n[^\n]*") + + (define (in-submodule s) `(module* sub #f ,s)) + (test '("module-begin\n10\n" "") go '(module-begin expression) in-submodule 'prop:procedure #:sub? #t) + (test '("module-begin\n10\n" "") go '(module-begin) in-submodule 'prop:procedure #:sub? #t) + (test '("module\n10\n" "") go '(module expression) in-submodule 'prop:procedure #:sub? #t) + (test '("module\n10\n" "") go '(module) in-submodule 'prop:procedure #:sub? #t) + (test '("expression\n10\n" "") go '(expression) in-submodule 'prop:procedure #:sub? #t) + (test '("" "m: not allowed in context\n expansion context: module") go '() in-submodule 'prop:procedure + #:trim-error #rx"^[^\n]*\n[^\n]*") + (test '("0\n" "") go '(module-begin expression) in-submodule 'prop:rename-transformer #:sub? #t) + (test '("0\n" "") go '(module-begin) in-submodule 'prop:rename-transformer #:sub? #t) + (test '("0\n" "") go '(module expression) in-submodule 'prop:rename-transformer #:sub? #t) + (test '("0\n" "") go '(module) in-submodule 'prop:rename-transformer #:sub? #t) + (test '("0\n" "") go '(expression) in-submodule 'prop:rename-transformer #:sub? #t) + (test '("" "m: not allowed in context\n expansion context: module") go '() in-submodule 'prop:rename-transformer + #:trim-error #rx"^[^\n]*\n[^\n]*") + + (define (in-defctx s) `(let () ,s)) + (test '("(#(struct:liberal-define-context))\n10\n" "") go '(definition-context expression) in-defctx 'prop:procedure) + (test '("(#(struct:liberal-define-context))\n10\n" "") go '(definition-context) in-defctx 'prop:procedure) + (test '("expression\n10\n" "") go '(expression) in-defctx 'prop:procedure) + (test '("" "m: not allowed in context\n expansion context: definition-context") go '() in-defctx 'prop:procedure + #:trim-error #rx"^[^\n]*\n[^\n]*") + (test '("0\n" "") go '(definition-context expression) in-defctx 'prop:rename-transformer) + (test '("0\n" "") go '(definition-context) in-defctx 'prop:rename-transformer) + (test '("0\n" "") go '(expression) in-defctx 'prop:rename-transformer) + (test '("" "m: not allowed in context\n expansion context: definition-context") go '() in-defctx 'prop:rename-transformer + #:trim-error #rx"^[^\n]*\n[^\n]*") + + (void)) + + + ;; ---------------------------------------- (let () @@ -1354,7 +1445,6 @@ (eval-syntax #'a) (eval-syntax (expand-syntax #'b)))]))) - ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 431033e2d2..7f0103a568 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -56,6 +56,7 @@ ROSYM static Scheme_Object *begin_symbol; ROSYM static Scheme_Object *disappeared_binding_symbol; ROSYM static Scheme_Object *compiler_inline_hint_symbol; ROSYM static Scheme_Object *app_symbol; +ROSYM static Scheme_Object *expression_symbol; ROSYM static Scheme_Object *datum_symbol; ROSYM static Scheme_Object *top_symbol; ROSYM static Scheme_Object *protected_symbol; @@ -301,6 +302,7 @@ void scheme_init_compile (Scheme_Env *env) env); REGISTER_SO(app_symbol); + REGISTER_SO(expression_symbol); REGISTER_SO(datum_symbol); REGISTER_SO(top_symbol); REGISTER_SO(protected_symbol); @@ -310,6 +312,7 @@ void scheme_init_compile (Scheme_Env *env) REGISTER_SO(call_with_values_symbol); app_symbol = scheme_intern_symbol("#%app"); + expression_symbol = scheme_intern_symbol("#%expression"); datum_symbol = scheme_intern_symbol("#%datum"); top_symbol = scheme_intern_symbol("#%top"); protected_symbol = scheme_intern_symbol("protected"); @@ -4403,13 +4406,58 @@ Scheme_Object *compile_list(Scheme_Object *form, Scheme_Comp_Env *env, return inner_compile_list(form, env, rec, drec, 0); } +static Scheme_Object *adjust_for_other_context(Scheme_Object *form, Scheme_Object *var, Scheme_Comp_Env *env) +{ + /* Macro doesn't expand in this context. In a module-begin context, + just don't expand. If it's not an expression + context and expression context is ok, then wrap as an + expression. Otherwise, we just have to complain. */ + if (env->flags & SCHEME_MODULE_BEGIN_FRAME) { + /* wrap in `begin` to trigger `#%module-begin` wrapper */ + var = scheme_datum_to_syntax(begin_symbol, scheme_false, scheme_sys_wraps(env), 0, 0); + var = scheme_make_pair(var, scheme_make_pair(form, scheme_null)); + form = scheme_datum_to_syntax(var, form, scheme_false, 0, 0); + } else if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), + scheme_frame_to_expansion_context_symbol(0))) { + /* expression is ok, so we must not be in an expression context */ + var = scheme_datum_to_syntax(expression_symbol, scheme_false, scheme_sys_wraps(env), 0, 0); + var = scheme_make_pair(var, scheme_make_pair(form, scheme_null)); + form = scheme_datum_to_syntax(var, form, scheme_false, 0, 0); + } else { + Scheme_Object *csym; + csym = scheme_frame_to_expansion_context_symbol(env->flags); + scheme_wrong_syntax(NULL, NULL, form, + "not allowed in context\n expansion context: %S", + csym); + return NULL; + } + + return form; +} + +static Scheme_Object *install_alt_from_rename(Scheme_Object *first, Scheme_Object *alt_first) +{ + if (alt_first) { + if (SCHEME_STX_PAIRP(first)) { + Scheme_Object *tail; + tail = scheme_stx_taint_disarm(first, NULL); + tail = SCHEME_STX_CDR(tail); + alt_first = scheme_datum_to_syntax(scheme_make_pair(alt_first, tail), + first, first, 0, 1); + return scheme_stx_track(alt_first, first, first); + } else + return alt_first; + } else + return first; +} + Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, Scheme_Comp_Env *env, Scheme_Compile_Expand_Info *rec, int drec, Scheme_Object **current_val, int keep_name) { - Scheme_Object *name, *val; + Scheme_Object *name, *val, *alt_first = NULL; Scheme_Expand_Info erec1; Scheme_Env *menv = NULL; @@ -4453,23 +4501,38 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, *current_val = val; if (!val) { + first = install_alt_from_rename(first, alt_first); SCHEME_EXPAND_OBSERVE_EXIT_CHECK(rec[drec].observer, first); return first; } else if (SAME_TYPE(SCHEME_TYPE(val), scheme_macro_type)) { - if (scheme_is_rename_transformer(SCHEME_PTR_VAL(val))) { - /* It's a rename. Look up the target name and try again. */ - name = scheme_transfer_srcloc(scheme_rename_transformer_id(SCHEME_PTR_VAL(val)), - name); - menv = NULL; - SCHEME_USE_FUEL(1); + if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(val), + scheme_frame_to_expansion_context_symbol(env->flags))) { + if (scheme_is_rename_transformer(SCHEME_PTR_VAL(val))) { + /* It's a rename. Look up the target name and try again. */ + Scheme_Object *new_name; + new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(val)); + if (!rec[drec].comp) + new_name = scheme_stx_track(new_name, name, name); + name = scheme_transfer_srcloc(new_name, name); + alt_first = name; + menv = NULL; + SCHEME_USE_FUEL(1); + } else { + alt_first = NULL; + scheme_init_expand_recs(rec, drec, &erec1, 1); + erec1.depth = 1; + erec1.value_name = (keep_name ? rec[drec].value_name : scheme_false); + first = scheme_expand_expr(first, env, &erec1, 0); + break; /* break to outer loop */ + } } else { - scheme_init_expand_recs(rec, drec, &erec1, 1); - erec1.depth = 1; - erec1.value_name = (keep_name ? rec[drec].value_name : scheme_false); - first = scheme_expand_expr(first, env, &erec1, 0); + first = install_alt_from_rename(first, alt_first); + alt_first = NULL; + first = adjust_for_other_context(first, val, env); break; /* break to outer loop */ } } else { + first = install_alt_from_rename(first, alt_first); SCHEME_EXPAND_OBSERVE_EXIT_CHECK(rec[drec].observer, first); return first; } @@ -4648,16 +4711,20 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { - /* It's a rename. Look up the target name and try again. */ - Scheme_Object *new_name; - new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var)); - if (!rec[drec].comp) { - new_name = scheme_stx_track(new_name, find_name, find_name); - } - find_name = scheme_transfer_srcloc(new_name, find_name); - SCHEME_USE_FUEL(1); - menv = NULL; - protected = 0; + if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), + scheme_frame_to_expansion_context_symbol(env->flags))) { + /* It's a rename. Look up the target name and try again. */ + Scheme_Object *new_name; + new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var)); + if (!rec[drec].comp) { + new_name = scheme_stx_track(new_name, find_name, find_name); + } + find_name = scheme_transfer_srcloc(new_name, find_name); + SCHEME_USE_FUEL(1); + menv = NULL; + protected = 0; + } else + break; } else break; } @@ -4771,15 +4838,19 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, SCHEME_EXPAND_OBSERVE_RESOLVE(rec[drec].observer, find_name); if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { - /* It's a rename. Look up the target name and try again. */ - Scheme_Object *new_name; - new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var)); - if (!rec[drec].comp) { - new_name = scheme_stx_track(new_name, find_name, find_name); - } - find_name = scheme_transfer_srcloc(new_name, find_name); - SCHEME_USE_FUEL(1); - menv = NULL; + if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), + scheme_frame_to_expansion_context_symbol(env->flags))) { + /* It's a rename. Look up the target name and try again. */ + Scheme_Object *new_name; + new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var)); + if (!rec[drec].comp) { + new_name = scheme_stx_track(new_name, find_name, find_name); + } + find_name = scheme_transfer_srcloc(new_name, find_name); + SCHEME_USE_FUEL(1); + menv = NULL; + } else + break; } else break; } @@ -4866,14 +4937,18 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { /* It's a rename. Look up the target name and try again. */ - Scheme_Object *new_name; - new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var)); - if (!rec[drec].comp) { - new_name = scheme_stx_track(new_name, find_name, find_name); - } - find_name = scheme_transfer_srcloc(new_name, find_name); - SCHEME_USE_FUEL(1); - menv = NULL; + if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), + scheme_frame_to_expansion_context_symbol(env->flags))) { + Scheme_Object *new_name; + new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var)); + if (!rec[drec].comp) { + new_name = scheme_stx_track(new_name, find_name, find_name); + } + find_name = scheme_transfer_srcloc(new_name, find_name); + SCHEME_USE_FUEL(1); + menv = NULL; + } else + break; } else break; } @@ -4976,14 +5051,18 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } SCHEME_EXPAND_OBSERVE_ENTER_MACRO(rec[drec].observer, form); - form = compile_expand_macro_app(name, menv, var, form, env, rec, drec, need_macro_scope); - SCHEME_EXPAND_OBSERVE_EXIT_MACRO(rec[drec].observer, form); + if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), + scheme_frame_to_expansion_context_symbol(env->flags))) { + form = compile_expand_macro_app(name, menv, var, form, env, rec, drec, need_macro_scope); - if (env->expand_result_adjust) { - Scheme_Expand_Result_Adjust_Proc adjust; - adjust = env->expand_result_adjust; - form = adjust(form, env->expand_result_adjust_arg); - } + if (env->expand_result_adjust) { + Scheme_Expand_Result_Adjust_Proc adjust; + adjust = env->expand_result_adjust; + form = adjust(form, env->expand_result_adjust_arg); + } + } else + form = adjust_for_other_context(form, var, env); + SCHEME_EXPAND_OBSERVE_EXIT_MACRO(rec[drec].observer, form); if (rec[drec].comp) goto top; diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index f1a704a83a..dd227d60fa 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,5 +1,5 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,0,1,0,0,8, 0,18,0,22,0,26,0,31,0,38,0,42,0,47,0,59,0,66,0,69,0, 82,0,89,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159, @@ -29,50 +29,50 @@ 251,22,90,2,19,248,22,102,199,12,249,22,80,2,20,248,22,104,201,27,248, 22,164,4,195,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,102,199, 249,22,80,2,20,248,22,104,201,12,27,248,22,82,248,22,164,4,196,28,248, -22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,163,20, -193,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,163,20,199,249,22, -80,2,4,248,22,164,20,201,11,18,143,10,2,28,27,248,22,82,248,22,164, +22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194,248,22,164,20, +193,249,22,157,4,80,143,42,39,251,22,90,2,19,248,22,164,20,199,249,22, +80,2,4,248,22,165,20,201,11,18,143,10,2,28,27,248,22,82,248,22,164, 4,196,28,248,22,88,193,20,14,144,40,39,40,28,248,22,88,248,22,82,194, -248,22,163,20,193,249,22,157,4,80,143,42,39,250,22,90,2,21,248,22,90, -249,22,90,248,22,90,2,22,248,22,163,20,201,251,22,90,2,19,2,22,2, -22,249,22,80,2,11,248,22,164,20,204,18,143,11,2,28,248,22,164,4,193, -27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22,164,20,195, +248,22,164,20,193,249,22,157,4,80,143,42,39,250,22,90,2,21,248,22,90, +249,22,90,248,22,90,2,22,248,22,164,20,201,251,22,90,2,19,2,22,2, +22,249,22,80,2,11,248,22,165,20,204,18,143,11,2,28,248,22,164,4,193, +27,248,22,164,4,194,249,22,80,248,22,90,248,22,81,196,248,22,165,20,195, 27,248,22,82,248,22,164,4,23,197,1,249,22,157,4,80,143,42,39,28,248, 22,64,248,22,158,4,248,22,81,23,198,2,27,249,22,2,32,0,88,148,8, 36,40,46,11,9,222,33,43,248,22,164,4,248,22,102,23,200,2,250,22,90, -2,23,248,22,90,249,22,90,248,22,90,248,22,163,20,23,204,2,250,22,91, +2,23,248,22,90,249,22,90,248,22,90,248,22,164,20,23,204,2,250,22,91, 2,24,249,22,2,22,81,23,204,2,248,22,104,23,206,2,249,22,80,248,22, -163,20,23,202,1,249,22,2,22,102,23,200,1,250,22,91,2,21,249,22,2, -32,0,88,148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,163,20, -201,248,22,164,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81, -196,248,22,164,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4, +164,20,23,202,1,249,22,2,22,102,23,200,1,250,22,91,2,21,249,22,2, +32,0,88,148,8,36,40,50,11,9,222,33,44,248,22,164,4,248,22,164,20, +201,248,22,165,20,198,27,248,22,164,4,194,249,22,80,248,22,90,248,22,81, +196,248,22,165,20,195,27,248,22,82,248,22,164,4,23,197,1,249,22,157,4, 80,143,42,39,250,22,91,2,23,249,22,2,32,0,88,148,8,36,40,50,11, -9,222,33,46,248,22,164,4,248,22,81,201,248,22,164,20,198,27,248,22,82, +9,222,33,46,248,22,164,4,248,22,81,201,248,22,165,20,198,27,248,22,82, 248,22,164,4,196,27,248,22,164,4,248,22,81,195,249,22,157,4,80,143,43, -39,28,248,22,88,195,250,22,91,2,21,9,248,22,164,20,199,250,22,90,2, -7,248,22,90,248,22,81,199,250,22,91,2,8,248,22,164,20,201,248,22,164, +39,28,248,22,88,195,250,22,91,2,21,9,248,22,165,20,199,250,22,90,2, +7,248,22,90,248,22,81,199,250,22,91,2,8,248,22,165,20,201,248,22,165, 20,202,27,248,22,82,248,22,164,4,196,27,248,22,164,4,248,22,81,195,249, -22,157,4,80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,164, +22,157,4,80,143,43,39,28,248,22,88,195,250,22,91,2,21,9,248,22,165, 20,199,250,22,90,2,21,248,22,90,248,22,81,199,250,22,91,2,9,248,22, -164,20,201,248,22,164,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249, +165,20,201,248,22,165,20,202,27,248,22,82,248,22,164,4,23,197,1,27,249, 22,1,22,94,249,22,2,22,164,4,248,22,164,4,248,22,81,199,248,22,185, 4,249,22,157,4,80,143,44,39,251,22,90,1,22,119,105,116,104,45,99,111, 110,116,105,110,117,97,116,105,111,110,45,109,97,114,107,2,25,250,22,91,1, 23,101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116, 105,111,110,21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109, 97,114,107,45,115,101,116,45,102,105,114,115,116,11,2,25,202,250,22,91,2, -21,9,248,22,164,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193, +21,9,248,22,165,20,204,27,248,22,82,248,22,164,4,196,28,248,22,88,193, 20,14,144,40,39,40,249,22,157,4,80,143,42,39,27,248,22,164,4,248,22, 81,197,28,249,22,169,9,64,61,62,248,22,158,4,248,22,102,196,250,22,90, -2,21,248,22,90,249,22,90,21,93,2,26,248,22,163,20,199,250,22,91,2, -5,249,22,90,2,26,249,22,90,248,22,111,203,2,26,248,22,164,20,202,251, -22,90,2,19,28,249,22,169,9,248,22,158,4,248,22,163,20,200,66,101,108, -115,101,10,248,22,163,20,197,250,22,91,2,21,9,248,22,164,20,200,249,22, -80,2,5,248,22,164,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248, +2,21,248,22,90,249,22,90,21,93,2,26,248,22,164,20,199,250,22,91,2, +5,249,22,90,2,26,249,22,90,248,22,111,203,2,26,248,22,165,20,202,251, +22,90,2,19,28,249,22,169,9,248,22,158,4,248,22,164,20,200,66,101,108, +115,101,10,248,22,164,20,197,250,22,91,2,21,9,248,22,165,20,200,249,22, +80,2,5,248,22,165,20,202,18,143,94,10,66,118,111,105,100,2,28,27,248, 22,82,248,22,164,4,196,249,22,157,4,80,143,42,39,28,248,22,64,248,22, -158,4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,163,20,199,248,22, -102,198,27,248,22,158,4,248,22,163,20,197,250,22,90,2,27,248,22,90,248, -22,81,197,250,22,91,2,24,248,22,164,20,199,248,22,164,20,202,144,39,20, +158,4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,164,20,199,248,22, +102,198,27,248,22,158,4,248,22,164,20,197,250,22,90,2,27,248,22,90,248, +22,81,197,250,22,91,2,24,248,22,165,20,199,248,22,165,20,202,144,39,20, 121,145,2,1,39,16,1,11,16,0,20,27,15,61,9,2,2,2,2,2,3, 11,11,11,11,9,9,11,11,11,10,39,80,143,39,39,20,121,145,2,1,39, 16,0,16,0,41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4,2, @@ -102,7 +102,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 2092); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,1,0,0,8, 0,16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,178,0, 193,0,211,0,223,0,239,0,253,0,19,1,39,1,73,1,90,1,107,1,130, @@ -185,292 +185,292 @@ 32,114,111,111,116,32,112,97,116,104,58,32,68,102,105,110,105,115,104,5,11, 80,76,84,67,79,76,76,69,67,84,83,1,20,99,111,108,108,101,99,116,115, 45,115,101,97,114,99,104,45,100,105,114,115,6,8,8,99,111,108,108,101,99, -116,115,27,248,22,174,15,194,28,192,192,28,248,22,153,7,194,27,248,22,133, -16,195,28,192,192,248,22,134,16,195,11,0,21,35,114,120,34,94,91,92,92, +116,115,27,248,22,175,15,194,28,192,192,28,248,22,153,7,194,27,248,22,134, +16,195,28,192,192,248,22,135,16,195,11,0,21,35,114,120,34,94,91,92,92, 93,91,92,92,93,91,63,93,91,92,92,93,34,0,6,35,114,120,34,47,34, 0,22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91,47,92,92,93, 42,36,34,0,19,35,114,120,34,91,32,46,93,43,40,91,47,92,92,93,42, -41,36,34,86,94,28,28,248,22,175,15,23,195,2,10,28,248,22,174,15,23, -195,2,10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248, -22,134,16,23,195,2,11,12,250,22,181,11,2,41,2,42,23,197,2,28,28, -248,22,175,15,23,195,2,249,22,169,9,248,22,176,15,23,197,2,2,43,249, +41,36,34,86,94,28,28,248,22,176,15,23,195,2,10,28,248,22,175,15,23, +195,2,10,28,248,22,153,7,23,195,2,28,248,22,134,16,23,195,2,10,248, +22,135,16,23,195,2,11,12,250,22,182,11,2,41,2,42,23,197,2,28,28, +248,22,176,15,23,195,2,249,22,169,9,248,22,177,15,23,197,2,2,43,249, 22,169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,196,2,23,195,2, -248,22,165,8,248,22,179,15,23,197,2,28,249,22,171,16,2,79,23,195,2, -28,248,22,153,7,195,248,22,182,15,195,194,27,248,22,128,8,23,195,1,249, -22,183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171,16,2,81,23, -201,2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80,144,47,40,41, -2,43,28,248,22,153,7,194,248,22,182,15,194,193,0,28,35,114,120,34,94, +248,22,165,8,248,22,180,15,23,197,2,28,249,22,172,16,2,79,23,195,2, +28,248,22,153,7,195,248,22,183,15,195,194,27,248,22,128,8,23,195,1,249, +22,184,15,248,22,168,8,250,22,180,16,2,80,28,249,22,172,16,2,81,23, +201,2,23,199,1,250,22,180,16,2,82,23,202,1,2,44,80,144,47,40,41, +2,43,28,248,22,153,7,194,248,22,183,15,194,193,0,28,35,114,120,34,94, 92,92,92,92,92,92,92,92,91,63,93,92,92,92,92,85,78,67,92,92,92, -92,34,86,95,28,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23, -195,2,28,248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,10,248, -22,175,15,23,195,2,12,252,22,181,11,2,6,2,45,39,23,199,2,23,200, -2,28,28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28, -248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,10,248,22,175,15, -23,196,2,12,252,22,181,11,2,6,2,45,40,23,199,2,23,200,2,27,28, -248,22,175,15,23,196,2,248,22,176,15,23,196,2,247,22,177,15,86,95,28, -28,248,22,135,16,23,196,2,10,249,22,169,9,247,22,177,15,23,195,2,12, -253,22,183,11,2,6,6,54,54,112,97,116,104,32,105,115,32,110,111,116,32, +92,34,86,95,28,28,28,248,22,175,15,23,195,2,10,28,248,22,153,7,23, +195,2,28,248,22,134,16,23,195,2,10,248,22,135,16,23,195,2,11,10,248, +22,176,15,23,195,2,12,252,22,182,11,2,6,2,45,39,23,199,2,23,200, +2,28,28,28,248,22,175,15,23,196,2,10,28,248,22,153,7,23,196,2,28, +248,22,134,16,23,196,2,10,248,22,135,16,23,196,2,11,10,248,22,176,15, +23,196,2,12,252,22,182,11,2,6,2,45,40,23,199,2,23,200,2,27,28, +248,22,176,15,23,196,2,248,22,177,15,23,196,2,247,22,178,15,86,95,28, +28,248,22,136,16,23,196,2,10,249,22,169,9,247,22,178,15,23,195,2,12, +253,22,184,11,2,6,6,54,54,112,97,116,104,32,105,115,32,110,111,116,32, 99,111,109,112,108,101,116,101,32,97,110,100,32,110,111,116,32,116,104,101,32, 112,108,97,116,102,111,114,109,39,115,32,99,111,110,118,101,110,116,105,111,110, 2,46,23,201,2,6,24,24,112,108,97,116,102,111,114,109,32,99,111,110,118, -101,110,116,105,111,110,32,116,121,112,101,247,22,177,15,28,249,22,169,9,28, -248,22,175,15,23,199,2,248,22,176,15,23,199,2,247,22,177,15,23,195,2, -12,253,22,183,11,2,6,6,37,37,103,105,118,101,110,32,112,97,116,104,115, +101,110,116,105,111,110,32,116,121,112,101,247,22,178,15,28,249,22,169,9,28, +248,22,176,15,23,199,2,248,22,177,15,23,199,2,247,22,178,15,23,195,2, +12,253,22,184,11,2,6,6,37,37,103,105,118,101,110,32,112,97,116,104,115, 32,117,115,101,32,100,105,102,102,101,114,101,110,116,32,99,111,110,118,101,110, 116,105,111,110,115,2,46,23,201,2,6,9,9,114,111,111,116,32,112,97,116, -104,23,202,2,27,27,248,22,139,16,28,248,22,135,16,23,199,2,23,198,1, -248,22,136,16,23,199,1,86,94,28,28,248,22,175,15,23,194,2,10,28,248, -22,174,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,133,16,23, -194,2,10,248,22,134,16,23,194,2,11,12,250,22,181,11,2,41,2,42,23, -196,2,28,28,248,22,175,15,23,194,2,249,22,169,9,248,22,176,15,23,196, +104,23,202,2,27,27,248,22,140,16,28,248,22,136,16,23,199,2,23,198,1, +248,22,137,16,23,199,1,86,94,28,28,248,22,176,15,23,194,2,10,28,248, +22,175,15,23,194,2,10,28,248,22,153,7,23,194,2,28,248,22,134,16,23, +194,2,10,248,22,135,16,23,194,2,11,12,250,22,182,11,2,41,2,42,23, +196,2,28,28,248,22,176,15,23,194,2,249,22,169,9,248,22,177,15,23,196, 2,2,43,249,22,169,9,247,22,180,8,2,43,27,28,248,22,153,7,23,195, -2,23,194,2,248,22,165,8,248,22,179,15,23,196,2,28,249,22,171,16,2, -79,23,195,2,28,248,22,153,7,194,248,22,182,15,194,193,27,248,22,128,8, -23,195,1,249,22,183,15,248,22,168,8,250,22,179,16,2,80,28,249,22,171, -16,2,81,23,201,2,23,199,1,250,22,179,16,2,82,23,202,1,2,44,80, -144,50,40,41,2,43,28,248,22,153,7,193,248,22,182,15,193,192,27,248,22, -179,15,23,195,2,28,249,22,169,9,23,197,2,66,117,110,105,120,28,249,22, -150,8,194,5,1,47,28,248,22,175,15,198,197,248,22,182,15,198,249,22,128, -16,199,249,22,183,15,249,22,153,8,248,22,179,15,200,40,198,28,249,22,169, -9,23,197,2,2,43,249,22,128,16,23,200,1,249,22,183,15,28,249,22,171, +2,23,194,2,248,22,165,8,248,22,180,15,23,196,2,28,249,22,172,16,2, +79,23,195,2,28,248,22,153,7,194,248,22,183,15,194,193,27,248,22,128,8, +23,195,1,249,22,184,15,248,22,168,8,250,22,180,16,2,80,28,249,22,172, +16,2,81,23,201,2,23,199,1,250,22,180,16,2,82,23,202,1,2,44,80, +144,50,40,41,2,43,28,248,22,153,7,193,248,22,183,15,193,192,27,248,22, +180,15,23,195,2,28,249,22,169,9,23,197,2,66,117,110,105,120,28,249,22, +150,8,194,5,1,47,28,248,22,176,15,198,197,248,22,183,15,198,249,22,129, +16,199,249,22,184,15,249,22,153,8,248,22,180,15,200,40,198,28,249,22,169, +9,23,197,2,2,43,249,22,129,16,23,200,1,249,22,184,15,28,249,22,172, 16,0,27,35,114,120,34,94,92,92,92,92,92,92,92,92,91,63,93,92,92, 92,92,91,97,45,122,93,58,34,23,199,2,251,22,154,8,2,47,250,22,153, -8,203,43,44,5,1,92,249,22,153,8,202,45,28,249,22,171,16,2,84,23, -199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,2,84, -23,199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,171,16,0, +8,203,43,44,5,1,92,249,22,153,8,202,45,28,249,22,172,16,2,84,23, +199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,172,16,2,84, +23,199,2,249,22,154,8,2,47,249,22,153,8,200,43,28,249,22,172,16,0, 14,35,114,120,34,94,92,92,92,92,92,92,92,92,34,23,199,2,249,22,154, -8,5,4,85,78,67,92,249,22,153,8,200,41,28,249,22,171,16,0,12,35, +8,5,4,85,78,67,92,249,22,153,8,200,41,28,249,22,172,16,0,12,35, 114,120,34,94,91,97,45,122,93,58,34,198,249,22,154,8,250,22,153,8,201, 39,40,249,22,153,8,200,41,12,198,12,32,86,88,148,8,36,42,56,11,72, 102,111,117,110,100,45,101,120,101,99,222,33,89,32,87,88,148,8,36,43,61, -11,66,110,101,120,116,222,33,88,27,248,22,137,16,23,196,2,28,249,22,171, -9,23,195,2,23,197,1,11,28,248,22,133,16,23,194,2,27,249,22,128,16, +11,66,110,101,120,116,222,33,88,27,248,22,138,16,23,196,2,28,249,22,171, +9,23,195,2,23,197,1,11,28,248,22,134,16,23,194,2,27,249,22,129,16, 23,197,1,23,196,1,28,23,197,2,90,144,42,11,89,146,42,39,11,248,22, -131,16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,2,27,248,22, -137,16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28,248,22,133, -16,23,194,2,250,2,86,23,205,2,23,206,2,249,22,128,16,23,200,2,23, +132,16,23,197,2,86,95,23,195,1,23,194,1,27,28,23,202,2,27,248,22, +138,16,23,199,2,28,249,22,171,9,23,195,2,23,200,2,11,28,248,22,134, +16,23,194,2,250,2,86,23,205,2,23,206,2,249,22,129,16,23,200,2,23, 198,1,250,2,86,23,205,2,23,206,2,23,196,1,11,28,23,193,2,192,86, -94,23,193,1,27,28,248,22,174,15,23,196,2,27,249,22,128,16,23,198,2, -23,205,2,28,28,248,22,187,15,193,10,248,22,186,15,193,192,11,11,28,23, -193,2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,137,16,23,200,2, -28,249,22,171,9,194,23,201,1,11,28,248,22,133,16,193,250,2,86,205,206, -249,22,128,16,200,197,250,2,86,205,206,195,192,86,94,23,194,1,28,23,196, -2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,2,86,95,23,195, -1,23,194,1,27,28,23,201,2,27,248,22,137,16,23,199,2,28,249,22,171, -9,23,195,2,23,200,2,11,28,248,22,133,16,23,194,2,250,2,86,23,204, -2,23,205,2,249,22,128,16,23,200,2,23,198,1,250,2,86,23,204,2,23, -205,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,174, -15,23,196,2,27,249,22,128,16,23,198,2,23,204,2,28,28,248,22,187,15, -193,10,248,22,186,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28, -23,202,2,11,27,248,22,137,16,23,200,2,28,249,22,171,9,194,23,201,1, -11,28,248,22,133,16,193,250,2,86,204,205,249,22,128,16,200,197,250,2,86, -204,205,195,192,28,23,193,2,90,144,42,11,89,146,42,39,11,248,22,131,16, +94,23,193,1,27,28,248,22,175,15,23,196,2,27,249,22,129,16,23,198,2, +23,205,2,28,28,248,22,188,15,193,10,248,22,187,15,193,192,11,11,28,23, +193,2,192,86,94,23,193,1,28,23,203,2,11,27,248,22,138,16,23,200,2, +28,249,22,171,9,194,23,201,1,11,28,248,22,134,16,193,250,2,86,205,206, +249,22,129,16,200,197,250,2,86,205,206,195,192,86,94,23,194,1,28,23,196, +2,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,2,86,95,23,195, +1,23,194,1,27,28,23,201,2,27,248,22,138,16,23,199,2,28,249,22,171, +9,23,195,2,23,200,2,11,28,248,22,134,16,23,194,2,250,2,86,23,204, +2,23,205,2,249,22,129,16,23,200,2,23,198,1,250,2,86,23,204,2,23, +205,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,175, +15,23,196,2,27,249,22,129,16,23,198,2,23,204,2,28,28,248,22,188,15, +193,10,248,22,187,15,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28, +23,202,2,11,27,248,22,138,16,23,200,2,28,249,22,171,9,194,23,201,1, +11,28,248,22,134,16,193,250,2,86,204,205,249,22,129,16,200,197,250,2,86, +204,205,195,192,28,23,193,2,90,144,42,11,89,146,42,39,11,248,22,132,16, 23,199,2,86,95,23,195,1,23,194,1,27,28,23,198,2,251,2,87,23,198, 2,23,203,2,23,201,2,23,202,2,11,28,23,193,2,192,86,94,23,193,1, -27,28,248,22,174,15,195,27,249,22,128,16,197,200,28,28,248,22,187,15,193, -10,248,22,186,15,193,192,11,11,28,192,192,28,198,11,251,2,87,198,203,201, +27,28,248,22,175,15,195,27,249,22,129,16,197,200,28,28,248,22,188,15,193, +10,248,22,187,15,193,192,11,11,28,192,192,28,198,11,251,2,87,198,203,201, 202,194,32,90,88,148,8,36,43,60,11,2,50,222,33,91,28,248,22,88,23, -197,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,201,2,23,196,2, -28,248,22,186,15,23,194,2,250,2,86,197,198,195,86,94,23,193,1,27,248, -22,164,20,23,199,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, -136,16,248,22,81,23,198,2,23,198,2,28,248,22,186,15,23,194,2,250,2, -86,199,200,195,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248,22,88, -23,194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,200, -2,28,248,22,186,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27, -248,22,164,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248, -22,136,16,248,22,81,197,201,28,248,22,186,15,193,250,2,86,203,204,195,251, -2,90,203,204,205,248,22,164,20,198,86,95,28,28,248,22,174,15,23,195,2, -10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134, -16,23,195,2,11,12,250,22,181,11,2,7,2,48,23,197,2,28,28,23,195, -2,28,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248, -22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,248,22,133,16,23,196, -2,11,10,12,250,22,181,11,2,7,6,45,45,40,111,114,47,99,32,35,102, +197,2,11,27,249,22,129,16,248,22,137,16,248,22,81,23,201,2,23,196,2, +28,248,22,187,15,23,194,2,250,2,86,197,198,195,86,94,23,193,1,27,248, +22,165,20,23,199,1,28,248,22,88,23,194,2,11,27,249,22,129,16,248,22, +137,16,248,22,81,23,198,2,23,198,2,28,248,22,187,15,23,194,2,250,2, +86,199,200,195,86,94,23,193,1,27,248,22,165,20,23,196,1,28,248,22,88, +23,194,2,11,27,249,22,129,16,248,22,137,16,248,22,81,23,198,2,23,200, +2,28,248,22,187,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27, +248,22,165,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,129,16,248, +22,137,16,248,22,81,197,201,28,248,22,187,15,193,250,2,86,203,204,195,251, +2,90,203,204,205,248,22,165,20,198,86,95,28,28,248,22,175,15,23,195,2, +10,28,248,22,153,7,23,195,2,28,248,22,134,16,23,195,2,10,248,22,135, +16,23,195,2,11,12,250,22,182,11,2,7,2,48,23,197,2,28,28,23,195, +2,28,28,248,22,175,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248, +22,134,16,23,196,2,10,248,22,135,16,23,196,2,11,248,22,134,16,23,196, +2,11,10,12,250,22,182,11,2,7,6,45,45,40,111,114,47,99,32,35,102, 32,40,97,110,100,47,99,32,112,97,116,104,45,115,116,114,105,110,103,63,32, 114,101,108,97,116,105,118,101,45,112,97,116,104,63,41,41,23,198,2,28,28, -248,22,133,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23, +248,22,134,16,23,195,2,90,144,42,11,89,146,42,39,11,248,22,132,16,23, 198,2,249,22,169,9,194,2,49,11,27,249,22,175,8,247,22,174,8,5,4, 80,65,84,72,27,28,23,194,2,249,80,143,43,44,249,22,165,8,23,198,1, 7,63,9,86,94,23,194,1,9,27,28,249,22,169,9,247,22,180,8,2,43, -249,22,80,248,22,183,15,5,1,46,23,196,1,23,194,1,28,248,22,88,23, -194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,200,2, -28,248,22,186,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248, -22,164,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248,22, -136,16,248,22,81,23,198,2,23,202,2,28,248,22,186,15,23,194,2,250,2, -86,203,204,195,86,94,23,193,1,27,248,22,164,20,23,196,1,28,248,22,88, -23,194,2,11,27,249,22,128,16,248,22,136,16,248,22,81,23,198,2,23,204, -2,28,248,22,186,15,23,194,2,250,2,86,205,206,195,86,94,23,193,1,27, -248,22,164,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,128,16,248, -22,136,16,248,22,81,197,205,28,248,22,186,15,193,250,2,86,23,15,23,16, -195,251,2,90,23,15,23,16,23,17,248,22,164,20,198,27,248,22,136,16,23, -196,1,28,248,22,186,15,193,250,2,86,198,199,195,11,250,80,144,42,43,42, +249,22,80,248,22,184,15,5,1,46,23,196,1,23,194,1,28,248,22,88,23, +194,2,11,27,249,22,129,16,248,22,137,16,248,22,81,23,198,2,23,200,2, +28,248,22,187,15,23,194,2,250,2,86,201,202,195,86,94,23,193,1,27,248, +22,165,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,129,16,248,22, +137,16,248,22,81,23,198,2,23,202,2,28,248,22,187,15,23,194,2,250,2, +86,203,204,195,86,94,23,193,1,27,248,22,165,20,23,196,1,28,248,22,88, +23,194,2,11,27,249,22,129,16,248,22,137,16,248,22,81,23,198,2,23,204, +2,28,248,22,187,15,23,194,2,250,2,86,205,206,195,86,94,23,193,1,27, +248,22,165,20,23,196,1,28,248,22,88,23,194,2,11,27,249,22,129,16,248, +22,137,16,248,22,81,197,205,28,248,22,187,15,193,250,2,86,23,15,23,16, +195,251,2,90,23,15,23,16,23,17,248,22,165,20,198,27,248,22,137,16,23, +196,1,28,248,22,187,15,193,250,2,86,198,199,195,11,250,80,144,42,43,42, 196,197,11,250,80,144,42,43,42,196,11,11,32,95,88,148,8,36,42,58,11, -2,50,222,33,97,0,8,35,114,120,35,34,92,34,34,27,249,22,167,16,23, +2,50,222,33,97,0,8,35,114,120,35,34,92,34,34,27,249,22,168,16,23, 197,2,23,198,2,28,23,193,2,86,94,23,196,1,27,248,22,102,23,195,2, -27,27,248,22,111,23,197,1,27,249,22,167,16,23,201,2,23,196,2,28,23, +27,27,248,22,111,23,197,1,27,249,22,168,16,23,201,2,23,196,2,28,23, 193,2,86,94,23,194,1,27,248,22,102,23,195,2,27,250,2,95,202,23,204, 1,248,22,111,23,199,1,27,28,249,22,169,9,247,22,180,8,2,43,250,22, -179,16,2,96,23,198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94, -202,195,249,22,80,248,22,183,15,195,195,86,95,23,199,1,23,193,1,27,28, -249,22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23,198,1,2,51, -194,28,249,22,150,8,194,2,51,249,22,94,200,9,249,22,80,248,22,183,15, -195,9,27,28,249,22,169,9,247,22,180,8,2,43,250,22,179,16,2,96,23, +180,16,2,96,23,198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94, +202,195,249,22,80,248,22,184,15,195,195,86,95,23,199,1,23,193,1,27,28, +249,22,169,9,247,22,180,8,2,43,250,22,180,16,2,96,23,198,1,2,51, +194,28,249,22,150,8,194,2,51,249,22,94,200,9,249,22,80,248,22,184,15, +195,9,27,28,249,22,169,9,247,22,180,8,2,43,250,22,180,16,2,96,23, 198,1,2,51,194,28,249,22,150,8,194,2,51,249,22,94,198,195,249,22,80, -248,22,183,15,195,195,86,94,23,193,1,27,28,249,22,169,9,247,22,180,8, -2,43,250,22,179,16,2,96,23,200,1,2,51,196,28,249,22,150,8,194,2, -51,249,22,94,196,9,249,22,80,248,22,183,15,195,9,86,95,28,28,248,22, -142,8,194,10,248,22,153,7,194,12,250,22,181,11,2,8,6,21,21,40,111, +248,22,184,15,195,195,86,94,23,193,1,27,28,249,22,169,9,247,22,180,8, +2,43,250,22,180,16,2,96,23,200,1,2,51,196,28,249,22,150,8,194,2, +51,249,22,94,196,9,249,22,80,248,22,184,15,195,9,86,95,28,28,248,22, +142,8,194,10,248,22,153,7,194,12,250,22,182,11,2,8,6,21,21,40,111, 114,47,99,32,98,121,116,101,115,63,32,115,116,114,105,110,103,63,41,196,28, -28,248,22,89,195,249,22,4,22,174,15,196,11,12,250,22,181,11,2,8,6, +28,248,22,89,195,249,22,4,22,175,15,196,11,12,250,22,182,11,2,8,6, 14,14,40,108,105,115,116,111,102,32,112,97,116,104,63,41,197,250,2,95,197, 195,28,248,22,153,7,197,248,22,167,8,197,196,28,28,248,22,0,23,195,2, 249,22,48,23,196,2,39,11,20,13,144,80,144,39,46,40,26,29,80,144,8, -29,47,40,249,22,31,11,80,144,8,31,46,40,22,144,15,10,22,145,15,10, -22,146,15,10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22, -151,15,10,22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156, -15,10,22,142,15,11,247,23,194,1,250,22,181,11,2,9,2,52,23,197,1, -86,94,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195,2,28, -248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,12,250,22,181,11, -23,196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,12,251,22,183,11, -23,197,1,2,53,2,46,23,198,1,86,94,28,28,248,22,174,15,23,195,2, -10,28,248,22,153,7,23,195,2,28,248,22,133,16,23,195,2,10,248,22,134, -16,23,195,2,11,12,250,22,181,11,23,196,2,2,48,23,197,2,28,248,22, -133,16,23,195,2,12,251,22,183,11,23,197,1,2,53,2,46,23,198,1,86, -94,86,94,28,28,248,22,174,15,23,195,2,10,28,248,22,153,7,23,195,2, -28,248,22,133,16,23,195,2,10,248,22,134,16,23,195,2,11,12,250,22,181, -11,23,196,2,2,48,23,197,2,28,248,22,133,16,23,195,2,86,94,23,194, -1,12,251,22,183,11,23,197,2,2,53,2,46,23,198,1,249,22,3,20,20, +29,47,40,249,22,31,11,80,144,8,31,46,40,22,145,15,10,22,146,15,10, +22,147,15,10,22,150,15,10,22,149,15,11,22,151,15,10,22,148,15,10,22, +152,15,10,22,153,15,10,22,154,15,10,22,155,15,10,22,156,15,11,22,157, +15,10,22,143,15,11,247,23,194,1,250,22,182,11,2,9,2,52,23,197,1, +86,94,28,28,248,22,175,15,23,195,2,10,28,248,22,153,7,23,195,2,28, +248,22,134,16,23,195,2,10,248,22,135,16,23,195,2,11,12,250,22,182,11, +23,196,2,2,48,23,197,2,28,248,22,134,16,23,195,2,12,251,22,184,11, +23,197,1,2,53,2,46,23,198,1,86,94,28,28,248,22,175,15,23,195,2, +10,28,248,22,153,7,23,195,2,28,248,22,134,16,23,195,2,10,248,22,135, +16,23,195,2,11,12,250,22,182,11,23,196,2,2,48,23,197,2,28,248,22, +134,16,23,195,2,12,251,22,184,11,23,197,1,2,53,2,46,23,198,1,86, +94,86,94,28,28,248,22,175,15,23,195,2,10,28,248,22,153,7,23,195,2, +28,248,22,134,16,23,195,2,10,248,22,135,16,23,195,2,11,12,250,22,182, +11,23,196,2,2,48,23,197,2,28,248,22,134,16,23,195,2,86,94,23,194, +1,12,251,22,184,11,23,197,2,2,53,2,46,23,198,1,249,22,3,20,20, 94,88,148,8,36,40,50,11,9,223,2,33,101,23,195,1,23,197,1,28,28, -248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22,181,11,23,196, -1,2,54,23,197,1,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22, -153,7,23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2, -11,12,250,22,181,11,2,15,2,48,23,196,2,28,248,22,133,16,23,194,2, -12,251,22,183,11,2,15,2,53,2,46,23,197,1,86,95,86,94,86,94,28, -28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,133, -16,23,196,2,10,248,22,134,16,23,196,2,11,12,250,22,181,11,2,15,2, -48,23,198,2,28,248,22,133,16,23,196,2,12,251,22,183,11,2,15,2,53, +248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250,22,182,11,23,196, +1,2,54,23,197,1,86,94,28,28,248,22,175,15,23,194,2,10,28,248,22, +153,7,23,194,2,28,248,22,134,16,23,194,2,10,248,22,135,16,23,194,2, +11,12,250,22,182,11,2,15,2,48,23,196,2,28,248,22,134,16,23,194,2, +12,251,22,184,11,2,15,2,53,2,46,23,197,1,86,95,86,94,86,94,28, +28,248,22,175,15,23,196,2,10,28,248,22,153,7,23,196,2,28,248,22,134, +16,23,196,2,10,248,22,135,16,23,196,2,11,12,250,22,182,11,2,15,2, +48,23,198,2,28,248,22,134,16,23,196,2,12,251,22,184,11,2,15,2,53, 2,46,23,199,2,249,22,3,32,0,88,148,8,36,40,49,11,9,222,33,104, 23,198,2,28,28,248,22,0,23,195,2,249,22,48,23,196,2,40,11,12,250, -22,181,11,2,15,2,54,23,197,2,252,80,143,44,52,23,199,1,23,200,1, -23,201,1,11,11,86,94,28,28,248,22,174,15,23,194,2,10,28,248,22,153, -7,23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11, -12,250,22,181,11,2,17,2,48,23,196,2,28,248,22,133,16,23,194,2,12, -251,22,183,11,2,17,2,53,2,46,23,197,1,86,96,86,94,28,28,248,22, -174,15,23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,133,16,23,197, -2,10,248,22,134,16,23,197,2,11,12,250,22,181,11,2,17,2,48,23,199, -2,28,248,22,133,16,23,197,2,12,251,22,183,11,2,17,2,53,2,46,23, -200,2,86,94,86,94,28,28,248,22,174,15,23,198,2,10,28,248,22,153,7, -23,198,2,28,248,22,133,16,23,198,2,10,248,22,134,16,23,198,2,11,12, -250,22,181,11,2,17,2,48,23,200,2,28,248,22,133,16,23,198,2,12,251, -22,183,11,2,17,2,53,2,46,23,201,2,249,22,3,32,0,88,148,8,36, +22,182,11,2,15,2,54,23,197,2,252,80,143,44,52,23,199,1,23,200,1, +23,201,1,11,11,86,94,28,28,248,22,175,15,23,194,2,10,28,248,22,153, +7,23,194,2,28,248,22,134,16,23,194,2,10,248,22,135,16,23,194,2,11, +12,250,22,182,11,2,17,2,48,23,196,2,28,248,22,134,16,23,194,2,12, +251,22,184,11,2,17,2,53,2,46,23,197,1,86,96,86,94,28,28,248,22, +175,15,23,197,2,10,28,248,22,153,7,23,197,2,28,248,22,134,16,23,197, +2,10,248,22,135,16,23,197,2,11,12,250,22,182,11,2,17,2,48,23,199, +2,28,248,22,134,16,23,197,2,12,251,22,184,11,2,17,2,53,2,46,23, +200,2,86,94,86,94,28,28,248,22,175,15,23,198,2,10,28,248,22,153,7, +23,198,2,28,248,22,134,16,23,198,2,10,248,22,135,16,23,198,2,11,12, +250,22,182,11,2,17,2,48,23,200,2,28,248,22,134,16,23,198,2,12,251, +22,184,11,2,17,2,53,2,46,23,201,2,249,22,3,32,0,88,148,8,36, 40,49,11,9,222,33,106,23,200,2,28,28,248,22,0,23,195,2,249,22,48, -23,196,2,40,11,12,250,22,181,11,2,17,2,54,23,197,2,252,80,143,44, -52,23,199,1,23,202,1,23,203,1,23,201,1,23,200,1,27,248,22,151,16, -2,55,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134, -16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16, -250,80,144,49,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86, -95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1, -27,250,80,144,44,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2, -248,22,138,16,23,194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42, -27,248,22,151,16,2,58,28,248,22,135,16,23,194,2,248,22,138,16,23,194, -1,28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131, -16,249,22,136,16,250,80,144,49,43,42,248,22,151,16,2,56,11,11,248,22, -151,16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23, -199,1,23,196,1,27,250,80,144,44,43,42,248,22,151,16,2,56,23,197,1, -10,28,23,193,2,248,22,138,16,23,194,1,11,249,80,144,41,55,40,40,80, +23,196,2,40,11,12,250,22,182,11,2,17,2,54,23,197,2,252,80,143,44, +52,23,199,1,23,202,1,23,203,1,23,201,1,23,200,1,27,248,22,152,16, +2,55,28,248,22,136,16,23,194,2,248,22,139,16,23,194,1,28,248,22,135, +16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249,22,137,16, +250,80,144,49,43,42,248,22,152,16,2,56,11,11,248,22,152,16,2,57,86, +95,23,195,1,23,194,1,248,22,139,16,249,22,137,16,23,199,1,23,196,1, +27,250,80,144,44,43,42,248,22,152,16,2,56,23,197,1,10,28,23,193,2, +248,22,139,16,23,194,1,11,249,80,144,41,55,40,39,80,144,41,8,40,42, +27,248,22,152,16,2,58,28,248,22,136,16,23,194,2,248,22,139,16,23,194, +1,28,248,22,135,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,132, +16,249,22,137,16,250,80,144,49,43,42,248,22,152,16,2,56,11,11,248,22, +152,16,2,57,86,95,23,195,1,23,194,1,248,22,139,16,249,22,137,16,23, +199,1,23,196,1,27,250,80,144,44,43,42,248,22,152,16,2,56,23,197,1, +10,28,23,193,2,248,22,139,16,23,194,1,11,249,80,144,41,55,40,40,80, 144,41,8,41,42,27,20,13,144,80,144,40,46,40,26,29,80,144,8,30,47, -40,249,22,31,11,80,144,8,32,46,40,22,144,15,10,22,145,15,10,22,146, -15,10,22,149,15,10,22,148,15,11,22,150,15,10,22,147,15,10,22,151,15, -10,22,152,15,10,22,153,15,10,22,154,15,10,22,155,15,11,22,156,15,10, -22,142,15,11,247,22,148,6,28,248,22,149,2,193,192,11,27,28,23,195,2, -249,22,128,16,23,197,1,6,11,11,99,111,110,102,105,103,46,114,107,116,100, -86,94,23,195,1,11,27,28,23,194,2,28,248,22,186,15,23,195,2,249,22, +40,249,22,31,11,80,144,8,32,46,40,22,145,15,10,22,146,15,10,22,147, +15,10,22,150,15,10,22,149,15,11,22,151,15,10,22,148,15,10,22,152,15, +10,22,153,15,10,22,154,15,10,22,155,15,10,22,156,15,11,22,157,15,10, +22,143,15,11,247,22,148,6,28,248,22,149,2,193,192,11,27,28,23,195,2, +249,22,129,16,23,197,1,6,11,11,99,111,110,102,105,103,46,114,107,116,100, +86,94,23,195,1,11,27,28,23,194,2,28,248,22,187,15,23,195,2,249,22, 140,6,23,196,1,80,144,43,8,42,42,11,11,28,192,192,21,17,1,0,250, 22,158,2,23,196,1,2,59,247,22,171,8,250,22,158,2,195,2,59,247,22, -171,8,28,248,22,153,7,23,195,2,27,248,22,182,15,23,196,1,28,248,22, -135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,43,54,42,28, -23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,142,8,23,195,2, -27,248,22,183,15,23,196,1,28,248,22,135,16,23,194,2,192,249,22,136,16, +171,8,28,248,22,153,7,23,195,2,27,248,22,183,15,23,196,1,28,248,22, +136,16,23,194,2,192,249,22,137,16,23,195,1,27,247,80,144,43,54,42,28, +23,193,2,192,86,94,23,193,1,247,22,153,16,28,248,22,142,8,23,195,2, +27,248,22,184,15,23,196,1,28,248,22,136,16,23,194,2,192,249,22,137,16, 23,195,1,27,247,80,144,43,54,42,28,23,193,2,192,86,94,23,193,1,247, -22,152,16,28,248,22,174,15,23,195,2,28,248,22,135,16,23,195,2,193,249, -22,136,16,23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23, -193,1,247,22,152,16,193,27,248,22,151,16,2,55,28,248,22,135,16,23,194, -2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89, -146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22,151, -16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22, -138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, -151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28, -248,22,135,16,23,195,2,193,249,22,136,16,23,196,1,27,249,80,144,44,55, -40,39,80,144,44,8,43,42,28,23,193,2,192,86,94,23,193,1,247,22,152, -16,28,248,22,135,16,23,195,2,248,22,138,16,23,195,1,28,248,22,134,16, -23,195,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250, -80,144,48,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95, -23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,200,1,23,196,1,27, -250,80,144,43,43,42,248,22,151,16,2,56,23,198,1,10,28,23,193,2,248, -22,138,16,23,194,1,11,28,248,22,88,23,196,2,9,28,248,22,81,23,196, -2,249,22,80,27,248,22,163,20,23,199,2,28,248,22,153,7,23,194,2,27, -248,22,182,15,23,195,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23, +22,153,16,28,248,22,175,15,23,195,2,28,248,22,136,16,23,195,2,193,249, +22,137,16,23,196,1,27,247,80,144,42,54,42,28,23,193,2,192,86,94,23, +193,1,247,22,153,16,193,27,248,22,152,16,2,55,28,248,22,136,16,23,194, +2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11,89, +146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,49,43,42,248,22,152, +16,2,56,11,11,248,22,152,16,2,57,86,95,23,195,1,23,194,1,248,22, +139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248,22, +152,16,2,56,23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11,28, +248,22,136,16,23,195,2,193,249,22,137,16,23,196,1,27,249,80,144,44,55, +40,39,80,144,44,8,43,42,28,23,193,2,192,86,94,23,193,1,247,22,153, +16,28,248,22,136,16,23,195,2,248,22,139,16,23,195,1,28,248,22,135,16, +23,195,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250, +80,144,48,43,42,248,22,152,16,2,56,11,11,248,22,152,16,2,57,86,95, +23,195,1,23,194,1,248,22,139,16,249,22,137,16,23,200,1,23,196,1,27, +250,80,144,43,43,42,248,22,152,16,2,56,23,198,1,10,28,23,193,2,248, +22,139,16,23,194,1,11,28,248,22,88,23,196,2,9,28,248,22,81,23,196, +2,249,22,80,27,248,22,164,20,23,199,2,28,248,22,153,7,23,194,2,27, +248,22,183,15,23,195,1,28,248,22,136,16,23,194,2,192,249,22,137,16,23, 195,1,27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22, -152,16,28,248,22,142,8,23,194,2,27,248,22,183,15,23,195,1,28,248,22, -135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,46,54,42,28, -23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22,174,15,23,194,2, -28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80,144,45, -54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,192,27,248,22,164, +153,16,28,248,22,142,8,23,194,2,27,248,22,184,15,23,195,1,28,248,22, +136,16,23,194,2,192,249,22,137,16,23,195,1,27,247,80,144,46,54,42,28, +23,193,2,192,86,94,23,193,1,247,22,153,16,28,248,22,175,15,23,194,2, +28,248,22,136,16,23,194,2,192,249,22,137,16,23,195,1,27,247,80,144,45, +54,42,28,23,193,2,192,86,94,23,193,1,247,22,153,16,192,27,248,22,165, 20,23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22, -80,248,80,144,45,60,42,248,22,163,20,23,197,2,27,248,22,164,20,23,197, +80,248,80,144,45,60,42,248,22,164,20,23,197,2,27,248,22,165,20,23,197, 1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80, -144,48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204,1, -248,22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, -204,1,248,22,164,20,23,198,1,249,22,94,23,199,2,27,248,22,164,20,23, +144,48,60,42,248,22,164,20,23,197,2,249,80,144,49,8,44,42,23,204,1, +248,22,165,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, +204,1,248,22,165,20,23,198,1,249,22,94,23,199,2,27,248,22,165,20,23, 197,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248, -80,144,48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204, -1,248,22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42, -23,204,1,248,22,164,20,23,198,1,249,22,94,23,196,2,27,248,22,164,20, +80,144,48,60,42,248,22,164,20,23,197,2,249,80,144,49,8,44,42,23,204, +1,248,22,165,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42, +23,204,1,248,22,165,20,23,198,1,249,22,94,23,196,2,27,248,22,165,20, 23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80, -248,80,144,45,60,42,248,22,163,20,23,197,2,27,248,22,164,20,23,197,1, +248,80,144,45,60,42,248,22,164,20,23,197,2,27,248,22,165,20,23,197,1, 28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80,144, -48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, -22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, -1,248,22,164,20,23,198,1,249,22,94,23,199,2,27,248,22,164,20,23,197, +48,60,42,248,22,164,20,23,197,2,249,80,144,49,8,44,42,23,204,1,248, +22,165,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23,204, +1,248,22,165,20,23,198,1,249,22,94,23,199,2,27,248,22,165,20,23,197, 1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,249,22,80,248,80, -144,48,60,42,248,22,163,20,23,197,2,249,80,144,49,8,44,42,23,204,1, -248,22,164,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, -204,1,248,22,164,20,23,198,1,27,250,22,158,2,23,198,1,23,199,1,11, -28,192,249,80,144,42,8,44,42,198,194,196,27,248,22,151,16,2,58,28,248, -22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2, -90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49, -43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1, -23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144, -44,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16, +144,48,60,42,248,22,164,20,23,197,2,249,80,144,49,8,44,42,23,204,1, +248,22,165,20,23,198,1,249,22,94,23,202,2,249,80,144,49,8,44,42,23, +204,1,248,22,165,20,23,198,1,27,250,22,158,2,23,198,1,23,199,1,11, +28,192,249,80,144,42,8,44,42,198,194,196,27,248,22,152,16,2,58,28,248, +22,136,16,23,194,2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2, +90,144,42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,49, +43,42,248,22,152,16,2,56,11,11,248,22,152,16,2,57,86,95,23,195,1, +23,194,1,248,22,139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144, +44,43,42,248,22,152,16,2,56,23,197,1,10,28,23,193,2,248,22,139,16, 23,194,1,11,27,248,80,144,41,58,42,249,80,144,43,55,40,40,80,144,43, 8,45,42,27,27,250,22,158,2,23,198,2,72,108,105,110,107,115,45,102,105, -108,101,11,27,28,23,194,2,23,194,1,86,94,23,194,1,249,22,128,16,27, +108,101,11,27,28,23,194,2,23,194,1,86,94,23,194,1,249,22,129,16,27, 250,22,158,2,23,202,2,71,115,104,97,114,101,45,100,105,114,11,28,192,192, -249,22,128,16,64,117,112,6,5,5,115,104,97,114,101,2,60,28,248,22,153, -7,23,194,2,27,248,22,182,15,23,195,1,28,248,22,135,16,23,194,2,192, -249,22,136,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94, -23,193,1,247,22,152,16,28,248,22,142,8,23,194,2,27,248,22,183,15,23, -195,1,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1,27,247,80, -144,47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16,28,248,22, -174,15,23,194,2,28,248,22,135,16,23,194,2,192,249,22,136,16,23,195,1, -27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,152,16, -192,250,22,94,248,22,90,11,28,247,22,159,16,28,247,22,160,16,248,22,90, -250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,204,2,2,59,247,22, -171,8,2,60,9,9,28,247,22,160,16,250,80,144,47,8,23,42,23,200,1, +249,22,129,16,64,117,112,6,5,5,115,104,97,114,101,2,60,28,248,22,153, +7,23,194,2,27,248,22,183,15,23,195,1,28,248,22,136,16,23,194,2,192, +249,22,137,16,23,195,1,27,247,80,144,47,54,42,28,23,193,2,192,86,94, +23,193,1,247,22,153,16,28,248,22,142,8,23,194,2,27,248,22,184,15,23, +195,1,28,248,22,136,16,23,194,2,192,249,22,137,16,23,195,1,27,247,80, +144,47,54,42,28,23,193,2,192,86,94,23,193,1,247,22,153,16,28,248,22, +175,15,23,194,2,28,248,22,136,16,23,194,2,192,249,22,137,16,23,195,1, +27,247,80,144,46,54,42,28,23,193,2,192,86,94,23,193,1,247,22,153,16, +192,250,22,94,248,22,90,11,28,247,22,160,16,28,247,22,161,16,248,22,90, +250,22,129,16,248,22,152,16,2,61,250,22,158,2,23,204,2,2,59,247,22, +171,8,2,60,9,9,28,247,22,161,16,250,80,144,47,8,23,42,23,200,1, 1,18,108,105,110,107,115,45,115,101,97,114,99,104,45,102,105,108,101,115,248, -22,90,23,200,1,9,248,22,173,13,23,194,1,249,22,14,80,144,41,8,26, -41,28,248,22,129,13,23,197,2,86,94,23,196,1,32,0,88,148,8,36,39, +22,90,23,200,1,9,248,22,174,13,23,194,1,249,22,14,80,144,41,8,26, +41,28,248,22,130,13,23,197,2,86,94,23,196,1,32,0,88,148,8,36,39, 44,11,9,222,11,20,20,94,88,148,8,36,39,46,11,9,223,3,33,124,23, 196,1,32,126,88,148,39,40,59,11,2,50,222,33,127,90,144,42,11,89,146, -42,39,11,248,22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22, -174,15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32, +42,39,11,248,22,132,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22, +175,15,23,194,2,28,248,22,188,15,23,194,2,249,22,145,6,23,195,1,32, 0,88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248, -22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194, -2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8, -36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23, -197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22, -187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11, -9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95, -23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194, +22,132,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,175,15,23,194, +2,28,248,22,188,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8, +36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,132,16,23, +197,1,86,95,23,195,1,23,194,1,28,248,22,175,15,23,194,2,28,248,22, +188,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11, +9,222,11,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,1,86,95, +23,195,1,23,194,1,28,248,22,175,15,23,194,2,28,248,22,188,15,23,194, 2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248, 2,126,23,194,1,11,11,11,11,32,128,2,88,148,8,36,40,58,11,2,50, 222,33,129,2,27,249,22,163,6,8,128,128,23,196,2,28,248,22,148,7,23, @@ -488,150 +488,150 @@ 22,148,7,23,194,2,9,249,22,80,23,195,1,248,2,128,2,23,211,1,192, 192,248,22,133,6,23,194,1,20,13,144,80,144,40,8,28,40,80,144,40,8, 46,42,27,28,249,22,189,8,248,22,180,8,2,62,41,90,144,42,11,89,146, -42,39,11,248,22,131,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22, -174,15,23,194,2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32, +42,39,11,248,22,132,16,23,198,2,86,95,23,195,1,23,194,1,28,248,22, +175,15,23,194,2,28,248,22,188,15,23,194,2,249,22,145,6,23,195,1,32, 0,88,148,8,36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248, -22,131,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194, -2,28,248,22,187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8, -36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23, -197,1,86,95,23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22, -187,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11, -9,222,11,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1,86,95, -23,195,1,23,194,1,28,248,22,174,15,23,194,2,28,248,22,187,15,23,194, +22,132,16,23,197,1,86,95,23,195,1,23,194,1,28,248,22,175,15,23,194, +2,28,248,22,188,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8, +36,39,44,11,9,222,11,90,144,42,11,89,146,42,39,11,248,22,132,16,23, +197,1,86,95,23,195,1,23,194,1,28,248,22,175,15,23,194,2,28,248,22, +188,15,23,194,2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11, +9,222,11,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,1,86,95, +23,195,1,23,194,1,28,248,22,175,15,23,194,2,28,248,22,188,15,23,194, 2,249,22,145,6,23,195,1,32,0,88,148,8,36,39,44,11,9,222,11,248, -2,126,23,194,1,11,11,11,11,11,28,248,22,186,15,23,195,2,27,28,249, +2,126,23,194,1,11,11,11,11,11,28,248,22,187,15,23,195,2,27,28,249, 22,189,8,248,22,180,8,2,62,41,249,22,145,6,23,197,2,32,0,88,148, 8,36,39,44,11,9,222,11,11,86,94,28,23,194,2,248,22,147,6,23,195, 1,86,94,23,194,1,12,249,22,80,27,248,22,188,5,23,199,1,250,22,44, 22,35,88,148,39,39,8,24,11,9,223,3,33,130,2,20,20,94,88,148,8, 36,39,46,11,9,223,3,33,131,2,23,196,1,194,249,22,80,11,194,28,28, -23,195,2,28,248,22,82,23,196,2,248,22,167,9,249,22,175,14,39,248,22, -164,20,23,199,2,11,11,194,86,94,23,195,1,249,22,12,20,20,94,88,148, +23,195,2,28,248,22,82,23,196,2,248,22,167,9,249,22,176,14,39,248,22, +165,20,23,199,2,11,11,194,86,94,23,195,1,249,22,12,20,20,94,88,148, 8,32,39,61,16,4,39,8,128,80,8,240,0,64,0,0,39,9,224,2,3, 33,132,2,23,196,1,80,144,41,8,26,41,27,248,22,167,9,194,28,192,192, -248,22,167,9,248,22,81,195,86,95,28,248,22,150,12,23,198,2,27,247,22, -142,12,28,249,22,132,12,23,195,2,2,63,251,22,138,12,23,197,1,2,63, +248,22,167,9,248,22,81,195,86,95,28,248,22,151,12,23,198,2,27,247,22, +143,12,28,249,22,133,12,23,195,2,2,63,251,22,139,12,23,197,1,2,63, 250,22,137,8,6,42,42,101,114,114,111,114,32,114,101,97,100,105,110,103,32, 99,111,108,108,101,99,116,105,111,110,32,108,105,110,107,115,32,102,105,108,101, -32,126,115,58,32,126,97,23,203,2,248,22,146,12,23,206,2,247,22,27,12, +32,126,115,58,32,126,97,23,203,2,248,22,147,12,23,206,2,247,22,27,12, 12,28,23,193,2,250,22,156,2,80,144,45,8,25,41,23,198,1,249,22,80, -23,198,1,21,17,0,0,86,95,23,195,1,23,193,1,12,28,248,22,150,12, +23,198,1,21,17,0,0,86,95,23,195,1,23,193,1,12,28,248,22,151,12, 23,198,2,86,94,23,197,1,248,23,195,1,247,22,138,2,196,88,148,39,40, 58,8,240,0,0,0,2,9,226,0,2,1,3,33,135,2,20,20,94,248,22, -148,6,23,194,2,28,248,22,148,7,248,22,148,6,23,195,1,12,248,22,177, +148,6,23,194,2,28,248,22,148,7,248,22,148,6,23,195,1,12,248,22,178, 11,6,30,30,101,120,112,101,99,116,101,100,32,97,32,115,105,110,103,108,101, 32,83,45,101,120,112,114,101,115,115,105,111,110,248,22,133,6,23,194,1,28, 248,22,89,193,28,28,249,22,128,4,41,248,22,93,195,10,249,22,128,4,42, 248,22,93,195,28,28,248,22,153,7,248,22,81,194,10,28,249,22,169,9,2, -64,248,22,163,20,195,10,249,22,169,9,2,65,248,22,163,20,195,28,27,248, -22,102,194,28,248,22,174,15,193,10,28,248,22,153,7,193,28,248,22,133,16, -193,10,248,22,134,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22, -180,16,248,22,111,195,11,11,11,11,28,248,22,187,15,249,22,128,16,23,196, -2,23,198,2,27,248,22,68,248,22,178,15,23,198,1,250,22,156,2,23,198, +64,248,22,164,20,195,10,249,22,169,9,2,65,248,22,164,20,195,28,27,248, +22,102,194,28,248,22,175,15,193,10,28,248,22,153,7,193,28,248,22,134,16, +193,10,248,22,135,16,193,11,27,248,22,88,248,22,104,195,28,192,192,248,22, +181,16,248,22,111,195,11,11,11,11,28,248,22,188,15,249,22,129,16,23,196, +2,23,198,2,27,248,22,68,248,22,179,15,23,198,1,250,22,156,2,23,198, 2,23,196,2,249,22,80,23,199,1,250,22,158,2,23,203,1,23,201,1,9, 12,250,22,156,2,23,197,1,23,198,1,249,22,80,23,198,1,23,201,1,28, -28,248,22,88,248,22,104,23,197,2,10,249,22,171,16,248,22,111,23,198,2, -247,22,171,8,27,248,22,138,16,249,22,136,16,248,22,102,23,200,2,23,198, -1,28,249,22,169,9,248,22,163,20,23,199,2,2,65,86,94,23,196,1,249, +28,248,22,88,248,22,104,23,197,2,10,249,22,172,16,248,22,111,23,198,2, +247,22,171,8,27,248,22,139,16,249,22,137,16,248,22,102,23,200,2,23,198, +1,28,249,22,169,9,248,22,164,20,23,199,2,2,65,86,94,23,196,1,249, 22,3,20,20,94,88,148,8,36,40,56,11,9,224,3,2,33,140,2,23,196, -1,248,22,141,16,23,196,1,28,249,22,169,9,248,22,163,20,23,199,2,2, +1,248,22,142,16,23,196,1,28,249,22,169,9,248,22,164,20,23,199,2,2, 64,86,94,23,196,1,86,94,28,250,22,158,2,23,197,2,11,11,12,250,22, 156,2,23,197,2,11,9,249,22,164,2,23,196,2,20,20,95,88,148,8,36, 41,53,11,9,224,3,2,33,141,2,23,195,1,23,196,1,27,248,22,68,248, -22,163,20,23,199,1,250,22,156,2,23,198,2,23,196,2,249,22,80,248,22, +22,164,20,23,199,1,250,22,156,2,23,198,2,23,196,2,249,22,80,248,22, 129,2,23,200,1,250,22,158,2,23,203,1,23,201,1,9,12,250,22,156,2, 23,196,1,23,197,1,248,22,95,23,199,1,27,28,28,23,194,2,248,22,167, 9,248,22,81,23,196,2,10,9,27,249,22,188,5,23,198,2,68,98,105,110, 97,114,121,250,22,44,22,35,88,148,8,36,39,47,11,9,223,3,33,137,2, 20,20,94,88,148,8,36,39,46,11,9,223,3,33,138,2,23,196,1,86,94, 28,28,248,22,89,23,194,2,249,22,4,32,0,88,148,8,36,40,48,11,9, -222,33,139,2,23,195,2,11,12,248,22,177,11,6,18,18,105,108,108,45,102, +222,33,139,2,23,195,2,11,12,248,22,178,11,6,18,18,105,108,108,45,102, 111,114,109,101,100,32,99,111,110,116,101,110,116,27,247,22,138,2,27,90,144, -42,11,89,146,42,39,11,248,22,131,16,23,201,2,192,86,96,249,22,3,20, +42,11,89,146,42,39,11,248,22,132,16,23,201,2,192,86,96,249,22,3,20, 20,94,88,148,8,36,40,57,11,9,224,2,3,33,142,2,23,195,1,23,197, 1,249,22,164,2,195,88,148,8,36,41,51,11,9,223,3,33,143,2,250,22, 156,2,80,144,47,8,25,41,23,200,1,249,22,80,23,201,1,198,193,20,13, 144,80,144,40,8,28,40,250,80,144,43,8,47,42,23,198,2,23,196,2,11, 27,250,22,158,2,80,144,44,8,25,41,23,197,2,21,143,11,17,0,0,27, 248,22,81,23,195,2,27,249,80,144,45,8,27,42,23,198,2,23,196,2,28, -249,22,171,9,23,195,2,23,196,1,248,22,164,20,195,86,94,23,195,1,20, +249,22,171,9,23,195,2,23,196,1,248,22,165,20,195,86,94,23,195,1,20, 13,144,80,144,43,8,28,40,250,80,144,46,8,47,42,23,201,1,23,199,2, 23,196,2,27,20,20,95,88,148,8,36,39,55,8,240,0,0,0,2,9,225, 5,4,1,33,144,2,23,194,1,23,197,1,28,249,22,48,23,195,2,39,20, 13,144,80,144,44,46,40,26,29,80,144,8,34,47,40,249,22,31,11,80,144, -8,36,46,40,22,144,15,10,22,145,15,10,22,146,15,10,22,149,15,10,22, -148,15,11,22,150,15,10,22,147,15,10,22,151,15,10,22,152,15,10,22,153, -15,10,22,154,15,10,22,155,15,11,22,156,15,10,22,142,15,11,247,23,193, -1,250,22,181,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39, +8,36,46,40,22,145,15,10,22,146,15,10,22,147,15,10,22,150,15,10,22, +149,15,11,22,151,15,10,22,148,15,10,22,152,15,10,22,153,15,10,22,154, +15,10,22,155,15,10,22,156,15,11,22,157,15,10,22,143,15,11,247,23,193, +1,250,22,182,11,2,9,2,52,23,196,1,248,22,8,20,20,94,88,148,39, 40,8,43,16,4,8,128,6,8,128,104,8,240,0,128,0,0,39,9,224,1, 2,33,145,2,23,195,1,0,7,35,114,120,34,47,43,34,28,248,22,153,7, -23,195,2,27,249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22, +23,195,2,27,249,22,170,16,2,147,2,23,197,2,28,23,193,2,28,249,22, 128,4,248,22,101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22, 7,250,22,175,7,23,200,1,39,248,22,101,23,199,1,23,198,1,249,22,7, 250,22,175,7,23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7, 23,201,1,248,22,103,23,200,1,23,200,1,249,22,7,23,197,1,23,198,1, -90,144,42,11,89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1, +90,144,42,11,89,146,42,39,11,248,22,132,16,23,198,1,86,94,23,195,1, 28,249,22,169,9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1, 23,200,1,27,249,22,80,23,197,1,23,201,1,28,248,22,153,7,23,195,2, -27,249,22,169,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128,4,248, +27,249,22,170,16,2,147,2,23,197,2,28,23,193,2,28,249,22,128,4,248, 22,101,23,196,2,248,22,182,3,248,22,156,7,23,199,2,249,22,7,250,22, 175,7,23,200,1,39,248,22,101,23,199,1,23,196,1,249,22,7,250,22,175, 7,23,200,2,39,248,22,101,23,199,2,249,22,80,249,22,175,7,23,201,1, 248,22,103,23,200,1,23,198,1,249,22,7,23,197,1,23,196,1,90,144,42, -11,89,146,42,39,11,248,22,131,16,23,198,1,86,94,23,195,1,28,249,22, +11,89,146,42,39,11,248,22,132,16,23,198,1,86,94,23,195,1,28,249,22, 169,9,23,195,2,2,49,86,94,23,193,1,249,22,7,23,196,1,23,198,1, 249,80,144,48,8,31,42,194,249,22,80,197,199,28,248,22,88,23,196,2,9, -28,248,22,81,23,196,2,28,248,22,149,2,248,22,163,20,23,197,2,250,22, -94,249,22,2,22,129,2,250,22,158,2,248,22,163,20,23,204,2,23,202,2, -9,250,22,158,2,248,22,163,20,23,202,2,11,9,27,248,22,164,20,23,200, +28,248,22,81,23,196,2,28,248,22,149,2,248,22,164,20,23,197,2,250,22, +94,249,22,2,22,129,2,250,22,158,2,248,22,164,20,23,204,2,23,202,2, +9,250,22,158,2,248,22,164,20,23,202,2,11,9,27,248,22,165,20,23,200, 1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2, -248,22,163,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248, -22,163,20,23,202,2,23,206,2,9,250,22,158,2,248,22,163,20,23,200,2, -11,9,249,80,144,48,8,48,42,23,203,1,248,22,164,20,23,199,1,27,248, -80,144,45,8,30,42,248,22,163,20,23,196,2,250,22,94,250,22,158,2,23, +248,22,164,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248, +22,164,20,23,202,2,23,206,2,9,250,22,158,2,248,22,164,20,23,200,2, +11,9,249,80,144,48,8,48,42,23,203,1,248,22,165,20,23,199,1,27,248, +80,144,45,8,30,42,248,22,164,20,23,196,2,250,22,94,250,22,158,2,23, 199,2,23,205,2,9,250,22,158,2,23,199,1,11,9,249,80,144,49,8,48, -42,23,204,1,248,22,164,20,23,200,1,249,22,94,247,22,155,16,249,80,144, -47,8,48,42,23,202,1,248,22,164,20,23,198,1,27,248,80,144,41,8,30, -42,248,22,163,20,23,198,2,250,22,94,250,22,158,2,23,199,2,23,201,2, -9,250,22,158,2,23,199,1,11,9,27,248,22,164,20,23,201,1,28,248,22, -88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,163,20, -23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,163,20,23, -202,2,23,207,2,9,250,22,158,2,248,22,163,20,23,200,2,11,9,249,80, -144,49,8,48,42,23,204,1,248,22,164,20,23,199,1,27,248,80,144,46,8, -30,42,248,22,163,20,23,196,2,250,22,94,250,22,158,2,23,199,2,23,206, +42,23,204,1,248,22,165,20,23,200,1,249,22,94,247,22,156,16,249,80,144, +47,8,48,42,23,202,1,248,22,165,20,23,198,1,27,248,80,144,41,8,30, +42,248,22,164,20,23,198,2,250,22,94,250,22,158,2,23,199,2,23,201,2, +9,250,22,158,2,23,199,1,11,9,27,248,22,165,20,23,201,1,28,248,22, +88,23,194,2,9,28,248,22,81,23,194,2,28,248,22,149,2,248,22,164,20, +23,195,2,250,22,94,249,22,2,22,129,2,250,22,158,2,248,22,164,20,23, +202,2,23,207,2,9,250,22,158,2,248,22,164,20,23,200,2,11,9,249,80, +144,49,8,48,42,23,204,1,248,22,165,20,23,199,1,27,248,80,144,46,8, +30,42,248,22,164,20,23,196,2,250,22,94,250,22,158,2,23,199,2,23,206, 2,9,250,22,158,2,23,199,1,11,9,249,80,144,50,8,48,42,23,205,1, -248,22,164,20,23,200,1,249,22,94,247,22,155,16,249,80,144,48,8,48,42, -23,203,1,248,22,164,20,23,198,1,249,22,94,247,22,155,16,27,248,22,164, +248,22,165,20,23,200,1,249,22,94,247,22,156,16,249,80,144,48,8,48,42, +23,203,1,248,22,165,20,23,198,1,249,22,94,247,22,156,16,27,248,22,165, 20,23,199,1,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248, -22,149,2,248,22,163,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22, -158,2,248,22,163,20,23,202,2,23,205,2,9,250,22,158,2,248,22,163,20, -23,200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,164,20,23,199, -1,27,248,80,144,44,8,30,42,248,22,163,20,23,196,2,250,22,94,250,22, +22,149,2,248,22,164,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22, +158,2,248,22,164,20,23,202,2,23,205,2,9,250,22,158,2,248,22,164,20, +23,200,2,11,9,249,80,144,47,8,48,42,23,202,1,248,22,165,20,23,199, +1,27,248,80,144,44,8,30,42,248,22,164,20,23,196,2,250,22,94,250,22, 158,2,23,199,2,23,204,2,9,250,22,158,2,23,199,1,11,9,249,80,144, -48,8,48,42,23,203,1,248,22,164,20,23,200,1,249,22,94,247,22,155,16, -249,80,144,46,8,48,42,23,201,1,248,22,164,20,23,198,1,32,150,2,88, +48,8,48,42,23,203,1,248,22,165,20,23,200,1,249,22,94,247,22,156,16, +249,80,144,46,8,48,42,23,201,1,248,22,165,20,23,198,1,32,150,2,88, 148,8,36,40,50,11,2,50,222,33,151,2,28,248,22,88,248,22,82,23,195, -2,248,22,90,27,248,22,163,20,195,28,248,22,174,15,193,248,22,178,15,193, -192,250,22,91,27,248,22,163,20,23,198,2,28,248,22,174,15,193,248,22,178, -15,193,192,2,67,248,2,150,2,248,22,164,20,23,198,1,250,22,137,8,6, +2,248,22,90,27,248,22,164,20,195,28,248,22,175,15,193,248,22,179,15,193, +192,250,22,91,27,248,22,164,20,23,198,2,28,248,22,175,15,193,248,22,179, +15,193,192,2,67,248,2,150,2,248,22,165,20,23,198,1,250,22,137,8,6, 7,7,10,32,126,97,32,126,97,6,1,1,32,23,196,1,249,22,137,8,6, 6,6,10,32,32,32,126,97,248,22,132,2,23,196,1,32,154,2,88,148,39, 41,51,11,68,102,105,108,116,101,114,222,33,155,2,28,248,22,88,23,195,2, -9,28,248,23,194,2,248,22,81,23,196,2,249,22,80,248,22,163,20,23,197, -2,249,2,154,2,23,197,1,248,22,164,20,23,199,1,249,2,154,2,23,195, -1,248,22,164,20,23,197,1,28,248,22,88,23,201,2,86,95,23,200,1,23, -199,1,28,23,201,2,28,197,249,22,128,16,202,199,200,27,28,248,22,88,23, +9,28,248,23,194,2,248,22,81,23,196,2,249,22,80,248,22,164,20,23,197, +2,249,2,154,2,23,197,1,248,22,165,20,23,199,1,249,2,154,2,23,195, +1,248,22,165,20,23,197,1,28,248,22,88,23,201,2,86,95,23,200,1,23, +199,1,28,23,201,2,28,197,249,22,129,16,202,199,200,27,28,248,22,88,23, 198,2,2,66,249,22,1,22,176,7,248,2,150,2,23,200,2,248,23,199,1, 251,22,137,8,6,70,70,99,111,108,108,101,99,116,105,111,110,32,110,111,116, 32,102,111,117,110,100,10,32,32,99,111,108,108,101,99,116,105,111,110,58,32, 126,115,10,32,32,105,110,32,99,111,108,108,101,99,116,105,111,110,32,100,105, 114,101,99,116,111,114,105,101,115,58,126,97,126,97,28,248,22,88,23,203,1, -28,248,22,174,15,23,202,2,248,22,178,15,23,202,1,23,201,1,250,22,176, -7,28,248,22,174,15,23,205,2,248,22,178,15,23,205,1,23,204,1,2,67, +28,248,22,175,15,23,202,2,248,22,179,15,23,202,1,23,201,1,250,22,176, +7,28,248,22,175,15,23,205,2,248,22,179,15,23,205,1,23,204,1,2,67, 23,201,2,249,22,1,22,176,7,249,22,2,32,0,88,148,8,36,40,48,11, -9,222,33,152,2,27,248,22,93,23,206,2,27,248,22,93,247,22,155,16,28, +9,222,33,152,2,27,248,22,93,23,206,2,27,248,22,93,247,22,156,16,28, 249,22,129,4,249,22,184,3,23,198,2,23,197,2,44,23,206,2,249,22,94, -247,22,155,16,248,22,90,249,22,137,8,6,50,50,46,46,46,32,91,126,97, +247,22,156,16,248,22,90,249,22,137,8,6,50,50,46,46,46,32,91,126,97, 32,97,100,100,105,116,105,111,110,97,108,32,108,105,110,107,101,100,32,97,110, 100,32,112,97,99,107,97,103,101,32,100,105,114,101,99,116,111,114,105,101,115, 93,249,22,184,3,23,201,1,23,200,1,28,249,22,5,22,131,2,23,202,2, @@ -640,311 +640,311 @@ 100,105,114,101,99,116,111,114,105,101,115,58,126,97,23,201,1,249,22,1,22, 176,7,249,22,2,32,0,88,148,8,36,40,48,11,9,222,33,153,2,249,2, 154,2,22,131,2,23,209,1,86,95,23,200,1,23,198,1,2,66,27,248,22, -81,23,202,2,27,28,248,22,174,15,23,195,2,249,22,128,16,23,196,1,23, -199,2,248,22,132,2,23,195,1,28,28,248,22,174,15,248,22,163,20,23,204, -2,248,22,187,15,23,194,2,10,27,250,22,1,22,128,16,23,197,1,23,202, -2,28,28,248,22,88,23,200,2,10,248,22,187,15,23,194,2,28,23,201,2, -28,28,250,80,144,45,8,32,42,195,203,204,10,27,28,248,22,174,15,202,248, -22,178,15,202,201,19,248,22,156,7,23,195,2,27,28,249,22,132,4,23,196, +81,23,202,2,27,28,248,22,175,15,23,195,2,249,22,129,16,23,196,1,23, +199,2,248,22,132,2,23,195,1,28,28,248,22,175,15,248,22,164,20,23,204, +2,248,22,188,15,23,194,2,10,27,250,22,1,22,129,16,23,197,1,23,202, +2,28,28,248,22,88,23,200,2,10,248,22,188,15,23,194,2,28,23,201,2, +28,28,250,80,144,45,8,32,42,195,203,204,10,27,28,248,22,175,15,202,248, +22,179,15,202,201,19,248,22,156,7,23,195,2,27,28,249,22,132,4,23,196, 4,43,28,249,22,159,7,6,4,4,46,114,107,116,249,22,175,7,23,199,2, 249,22,184,3,23,200,4,43,249,22,176,7,250,22,175,7,23,200,1,39,249, 22,184,3,23,201,4,43,6,3,3,46,115,115,86,94,23,195,1,11,11,28, 23,193,2,250,80,144,48,8,32,42,198,23,196,1,23,15,11,2,28,200,249, -22,128,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16, -23,17,248,22,164,20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8, -49,42,204,205,206,23,15,23,16,23,17,248,22,164,20,23,19,23,19,26,8, -80,144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,164,20,23,18,23, +22,129,16,194,202,192,26,8,80,144,50,8,49,42,204,205,206,23,15,23,16, +23,17,248,22,165,20,23,19,28,23,19,23,19,200,192,26,8,80,144,50,8, +49,42,204,205,206,23,15,23,16,23,17,248,22,165,20,23,19,23,19,26,8, +80,144,49,8,49,42,203,204,205,206,23,15,23,16,248,22,165,20,23,18,23, 18,90,144,41,11,89,146,41,39,11,249,80,144,43,8,31,42,23,199,1,23, -200,1,27,248,22,68,28,248,22,174,15,195,248,22,178,15,195,194,27,27,247, -22,156,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22, -149,2,248,22,163,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158, -2,248,22,163,20,23,202,2,23,203,2,9,250,22,158,2,248,22,163,20,23, -200,2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,164,20,23,199,1, -27,248,80,144,46,8,30,42,248,22,163,20,23,196,2,250,22,94,250,22,158, +200,1,27,248,22,68,28,248,22,175,15,195,248,22,179,15,195,194,27,27,247, +22,157,16,28,248,22,88,23,194,2,9,28,248,22,81,23,194,2,28,248,22, +149,2,248,22,164,20,23,195,2,250,22,94,249,22,2,22,129,2,250,22,158, +2,248,22,164,20,23,202,2,23,203,2,9,250,22,158,2,248,22,164,20,23, +200,2,11,9,249,80,144,49,8,48,42,23,200,1,248,22,165,20,23,199,1, +27,248,80,144,46,8,30,42,248,22,164,20,23,196,2,250,22,94,250,22,158, 2,23,199,2,23,202,2,9,250,22,158,2,23,199,1,11,9,249,80,144,50, -8,48,42,23,201,1,248,22,164,20,23,200,1,249,22,94,247,22,155,16,249, -80,144,48,8,48,42,23,199,1,248,22,164,20,23,198,1,26,8,80,144,51, +8,48,42,23,201,1,248,22,165,20,23,200,1,249,22,94,247,22,156,16,249, +80,144,48,8,48,42,23,199,1,248,22,165,20,23,198,1,26,8,80,144,51, 8,49,42,200,202,203,205,23,16,23,17,200,11,32,158,2,88,148,8,36,42, 59,11,2,50,222,33,159,2,28,248,22,133,4,23,196,2,86,94,23,195,1, -19,248,22,147,8,23,195,2,19,248,22,147,8,23,196,2,249,22,184,15,27, +19,248,22,147,8,23,195,2,19,248,22,147,8,23,196,2,249,22,185,15,27, 251,22,154,8,250,22,153,8,23,205,2,39,23,204,4,2,51,249,22,153,8, 23,204,1,23,202,4,2,68,28,248,22,133,4,248,22,147,8,23,195,2,86, -94,23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248,22,175,15, -198,248,22,176,15,198,247,22,177,15,2,2,27,248,22,182,3,23,197,1,28, +94,23,193,1,251,22,184,11,2,37,2,69,2,70,202,192,28,248,22,176,15, +198,248,22,177,15,198,247,22,178,15,2,2,27,248,22,182,3,23,197,1,28, 249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27,248,22,181,3, -23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23, +23,195,2,249,22,185,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23, 204,1,2,71,249,22,153,8,23,204,1,23,202,1,2,68,28,248,22,133,4, -248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2, -70,202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,250,2,158, -2,196,197,195,248,22,186,15,27,250,22,128,16,23,200,1,23,202,1,23,199, -1,28,249,22,169,9,23,197,2,66,115,97,109,101,192,28,248,22,133,16,23, -196,2,249,22,128,16,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249, +248,22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2, +70,202,192,28,248,22,176,15,198,248,22,177,15,198,247,22,178,15,250,2,158, +2,196,197,195,248,22,187,15,27,250,22,129,16,23,200,1,23,202,1,23,199, +1,28,249,22,169,9,23,197,2,66,115,97,109,101,192,28,248,22,134,16,23, +196,2,249,22,129,16,194,196,249,80,144,46,42,42,23,195,1,23,197,1,249, 22,5,20,20,96,88,148,39,40,54,47,9,226,5,4,2,6,33,160,2,23, -199,1,23,195,1,23,197,1,23,196,1,27,248,22,186,15,249,22,128,16,23, +199,1,23,195,1,23,197,1,23,196,1,27,248,22,187,15,249,22,129,16,23, 198,2,23,199,2,28,23,193,2,192,86,94,23,193,1,28,23,197,1,27,90, 144,41,11,89,146,41,39,11,250,80,144,46,8,34,42,23,202,2,2,68,2, -37,27,248,22,180,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248, -22,147,8,23,198,1,28,248,22,175,15,195,249,22,128,16,196,194,192,27,247, -22,157,16,249,22,5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3, -33,161,2,23,196,1,23,195,1,23,199,1,247,22,158,16,11,86,95,28,28, -248,22,175,15,23,194,2,10,28,248,22,174,15,23,194,2,10,28,248,22,153, -7,23,194,2,28,248,22,133,16,23,194,2,10,248,22,134,16,23,194,2,11, -12,252,22,181,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22, +37,27,248,22,181,15,23,196,1,27,250,2,158,2,23,197,2,23,204,1,248, +22,147,8,23,198,1,28,248,22,176,15,195,249,22,129,16,196,194,192,27,247, +22,158,16,249,22,5,20,20,96,88,148,39,40,51,47,9,226,5,6,2,3, +33,161,2,23,196,1,23,195,1,23,199,1,247,22,159,16,11,86,95,28,28, +248,22,176,15,23,194,2,10,28,248,22,175,15,23,194,2,10,28,248,22,153, +7,23,194,2,28,248,22,134,16,23,194,2,10,248,22,135,16,23,194,2,11, +12,252,22,182,11,23,200,2,2,42,39,23,198,2,23,199,2,28,28,248,22, 153,7,23,195,2,10,248,22,142,8,23,195,2,86,94,23,194,1,12,252,22, -181,11,23,200,2,2,72,40,23,198,2,23,199,1,90,144,42,11,89,146,42, -39,11,248,22,131,16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86, -95,23,198,1,23,196,1,12,250,22,184,11,23,201,1,2,73,23,199,1,249, +182,11,23,200,2,2,72,40,23,198,2,23,199,1,90,144,42,11,89,146,42, +39,11,248,22,132,16,23,197,2,86,94,23,195,1,86,94,28,23,193,2,86, +95,23,198,1,23,196,1,12,250,22,185,11,23,201,1,2,73,23,199,1,249, 22,7,23,195,1,23,196,1,32,164,2,88,148,8,36,46,61,11,2,74,222, -33,165,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2,39,23, +33,165,2,249,22,185,15,27,251,22,154,8,250,22,153,8,23,203,2,39,23, 207,1,23,205,1,249,23,203,1,23,202,1,23,208,1,28,248,22,153,7,23, 204,2,249,22,168,8,23,205,1,8,63,23,203,1,28,248,22,133,4,248,22, -147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,201, -192,28,248,22,175,15,197,248,22,176,15,197,247,22,177,15,32,166,2,88,148, +147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2,70,201, +192,28,248,22,176,15,197,248,22,177,15,197,247,22,178,15,32,166,2,88,148, 8,36,45,8,24,11,2,50,222,33,167,2,28,248,22,133,4,23,199,2,86, 95,23,198,1,23,194,1,19,248,22,147,8,23,195,2,19,248,22,147,8,23, -196,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204, +196,2,249,22,185,15,27,251,22,154,8,250,22,153,8,23,205,2,39,23,204, 4,2,51,249,23,206,1,23,204,1,23,202,4,28,248,22,153,7,23,207,2, 249,22,168,8,23,208,1,8,63,23,206,1,28,248,22,133,4,248,22,147,8, -23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,204,192,28, -248,22,175,15,200,248,22,176,15,200,247,22,177,15,2,2,27,248,22,182,3, +23,195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2,70,204,192,28, +248,22,176,15,200,248,22,177,15,200,247,22,178,15,2,2,27,248,22,182,3, 23,200,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197,2,27, -248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23, +248,22,181,3,23,195,2,249,22,185,15,27,251,22,154,8,250,22,153,8,23, 205,2,39,23,204,1,23,203,1,249,23,206,1,23,204,1,23,202,1,28,248, 22,153,7,23,207,2,249,22,168,8,23,208,1,8,63,23,206,1,28,248,22, -133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2, -69,2,70,204,192,28,248,22,175,15,200,248,22,176,15,200,247,22,177,15,28, +133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37,2, +69,2,70,204,192,28,248,22,176,15,200,248,22,177,15,200,247,22,178,15,28, 248,22,133,4,23,194,2,86,95,23,195,1,23,193,1,19,248,22,147,8,23, -196,2,19,248,22,147,8,23,197,2,249,22,184,15,27,251,22,154,8,250,22, +196,2,19,248,22,147,8,23,197,2,249,22,185,15,27,251,22,154,8,250,22, 153,8,23,206,2,39,23,204,4,2,51,249,23,207,1,23,205,1,23,202,4, 28,248,22,153,7,23,208,2,249,22,168,8,23,209,1,8,63,23,207,1,28, -248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2, -37,2,69,2,70,205,192,28,248,22,175,15,201,248,22,176,15,201,247,22,177, +248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2, +37,2,69,2,70,205,192,28,248,22,176,15,201,248,22,177,15,201,247,22,178, 15,2,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22,148, -8,23,199,2,23,197,2,27,248,22,181,3,23,195,2,249,22,184,15,27,251, +8,23,199,2,23,197,2,27,248,22,181,3,23,195,2,249,22,185,15,27,251, 22,154,8,250,22,153,8,23,206,2,39,23,204,1,23,204,1,249,23,207,1, 23,205,1,23,202,1,28,248,22,153,7,23,208,2,249,22,168,8,23,209,1, 8,63,23,207,1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193, -1,251,22,183,11,2,37,2,69,2,70,205,192,28,248,22,175,15,201,248,22, -176,15,201,247,22,177,15,28,248,22,133,4,193,254,2,164,2,201,203,204,205, +1,251,22,184,11,2,37,2,69,2,70,205,192,28,248,22,176,15,201,248,22, +177,15,201,247,22,178,15,28,248,22,133,4,193,254,2,164,2,201,203,204,205, 248,22,147,8,202,2,51,248,22,147,8,202,27,248,22,182,3,194,28,249,22, 169,9,8,46,249,22,148,8,199,196,254,2,164,2,202,204,205,206,199,203,248, 22,181,3,200,253,2,166,2,201,202,203,204,205,198,90,144,41,11,89,146,41, -39,11,86,95,28,28,248,22,175,15,23,199,2,10,28,248,22,174,15,23,199, -2,10,28,248,22,153,7,23,199,2,28,248,22,133,16,23,199,2,10,248,22, -134,16,23,199,2,11,12,252,22,181,11,23,200,2,2,42,39,23,203,2,23, +39,11,86,95,28,28,248,22,176,15,23,199,2,10,28,248,22,175,15,23,199, +2,10,28,248,22,153,7,23,199,2,28,248,22,134,16,23,199,2,10,248,22, +135,16,23,199,2,11,12,252,22,182,11,23,200,2,2,42,39,23,203,2,23, 204,2,28,28,248,22,153,7,23,200,2,10,248,22,142,8,23,200,2,12,252, -22,181,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146, -42,39,11,248,22,131,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250, -22,184,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,180,15, +22,182,11,23,200,2,2,72,40,23,203,2,23,204,2,90,144,42,11,89,146, +42,39,11,248,22,132,16,23,202,2,86,94,23,195,1,86,94,28,192,12,250, +22,185,11,23,201,1,2,73,23,204,2,249,22,7,194,195,27,248,22,181,15, 23,196,1,27,19,248,22,147,8,23,196,2,28,248,22,133,4,23,194,4,86, 94,23,199,1,19,248,22,147,8,23,197,2,19,248,22,147,8,23,198,2,249, -22,184,15,27,251,22,154,8,250,22,153,8,23,207,2,39,23,204,4,2,51, +22,185,15,27,251,22,154,8,250,22,153,8,23,207,2,39,23,204,4,2,51, 249,23,211,1,23,206,1,23,202,4,28,248,22,153,7,23,212,2,249,22,168, 8,23,213,1,8,63,23,211,1,28,248,22,133,4,248,22,147,8,23,195,2, -86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,23,17,192,28,248,22, -175,15,205,248,22,176,15,205,247,22,177,15,2,2,27,248,22,182,3,23,195, +86,94,23,193,1,251,22,184,11,2,37,2,69,2,70,23,17,192,28,248,22, +176,15,205,248,22,177,15,205,247,22,178,15,2,2,27,248,22,182,3,23,195, 4,28,249,22,169,9,8,46,249,22,148,8,23,200,2,23,197,2,27,248,22, -181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,207,2, +181,3,23,195,2,249,22,185,15,27,251,22,154,8,250,22,153,8,23,207,2, 39,23,204,1,23,208,1,249,23,211,1,23,206,1,23,202,1,28,248,22,153, 7,23,212,2,249,22,168,8,23,213,1,8,63,23,211,1,28,248,22,133,4, -248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2, -70,23,17,192,28,248,22,175,15,205,248,22,176,15,205,247,22,177,15,28,248, +248,22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2, +70,23,17,192,28,248,22,176,15,205,248,22,177,15,205,247,22,178,15,28,248, 22,133,4,23,194,2,86,95,23,200,1,23,193,1,254,2,164,2,23,203,2, 23,208,1,23,209,1,23,210,1,248,22,147,8,23,204,2,2,51,248,22,147, 8,23,204,1,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249,22, 148,8,23,201,2,23,197,2,254,2,164,2,23,204,1,23,209,1,23,210,1, 23,211,1,23,200,2,23,208,1,248,22,181,3,23,201,1,253,2,166,2,23, 203,1,23,207,1,23,208,1,23,209,1,23,210,1,23,199,1,2,28,248,22, -175,15,195,249,22,128,16,196,194,192,32,169,2,88,148,8,36,43,61,11,2, +176,15,195,249,22,129,16,196,194,192,32,169,2,88,148,8,36,43,61,11,2, 50,222,33,170,2,28,248,22,133,4,23,197,2,86,94,23,196,1,19,248,22, -147,8,23,195,2,35,248,22,147,8,23,196,2,249,22,184,15,27,251,22,154, +147,8,23,195,2,35,248,22,147,8,23,196,2,249,22,185,15,27,251,22,154, 8,250,22,153,8,23,205,1,39,23,204,4,2,51,2,51,28,248,22,153,7, 23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248, -22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, -202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,27,248,22, +22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2,70, +202,192,28,248,22,176,15,198,248,22,177,15,198,247,22,178,15,2,27,248,22, 182,3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23,197, -2,35,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22,153, +2,35,248,22,181,3,23,195,2,249,22,185,15,27,251,22,154,8,250,22,153, 8,23,205,1,39,23,204,1,2,51,2,51,28,248,22,153,7,23,205,2,249, 22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248,22,147,8,23, -195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70,202,192,28,248, -22,175,15,198,248,22,176,15,198,247,22,177,15,28,248,22,133,4,23,194,2, +195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2,70,202,192,28,248, +22,176,15,198,248,22,177,15,198,247,22,178,15,28,248,22,133,4,23,194,2, 86,94,23,193,1,19,248,22,147,8,23,196,2,35,248,22,147,8,23,197,2, -249,22,184,15,27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,4,2, +249,22,185,15,27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,4,2, 51,2,51,28,248,22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23, 205,1,28,248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22, -183,11,2,37,2,69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199, -247,22,177,15,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249, -22,148,8,23,199,2,23,197,2,35,248,22,181,3,23,195,2,249,22,184,15, +184,11,2,37,2,69,2,70,203,192,28,248,22,176,15,199,248,22,177,15,199, +247,22,178,15,2,27,248,22,182,3,23,195,1,28,249,22,169,9,8,46,249, +22,148,8,23,199,2,23,197,2,35,248,22,181,3,23,195,2,249,22,185,15, 27,251,22,154,8,250,22,153,8,23,206,1,39,23,204,1,2,51,2,51,28, 248,22,153,7,23,206,2,249,22,168,8,23,207,1,8,63,23,205,1,28,248, -22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37, -2,69,2,70,203,192,28,248,22,175,15,199,248,22,176,15,199,247,22,177,15, +22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37, +2,69,2,70,203,192,28,248,22,176,15,199,248,22,177,15,199,247,22,178,15, 251,2,169,2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28, -248,22,175,15,23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153, -7,23,196,2,28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11, -12,252,22,181,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153, -7,23,197,2,10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72, -40,23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23, -199,2,86,94,23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23, -201,2,249,22,7,194,195,27,248,22,180,15,23,196,1,27,251,2,169,2,23, -198,2,23,201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195, -249,22,128,16,196,194,192,2,51,252,80,144,44,8,35,42,2,37,2,51,32, +248,22,176,15,23,196,2,10,28,248,22,175,15,23,196,2,10,28,248,22,153, +7,23,196,2,28,248,22,134,16,23,196,2,10,248,22,135,16,23,196,2,11, +12,252,22,182,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153, +7,23,197,2,10,248,22,142,8,23,197,2,12,252,22,182,11,2,37,2,72, +40,23,200,2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,132,16,23, +199,2,86,94,23,195,1,86,94,28,192,12,250,22,185,11,2,37,2,73,23, +201,2,249,22,7,194,195,27,248,22,181,15,23,196,1,27,251,2,169,2,23, +198,2,23,201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,176,15,195, +249,22,129,16,196,194,192,2,51,252,80,144,44,8,35,42,2,37,2,51,32, 0,88,148,8,36,41,46,11,9,222,33,172,2,198,199,32,174,2,88,148,8, 36,43,60,11,2,50,222,33,177,2,32,175,2,88,148,8,36,45,60,11,2, -74,222,33,176,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,203,2, +74,222,33,176,2,249,22,185,15,27,251,22,154,8,250,22,153,8,23,203,2, 39,23,206,1,23,204,1,249,22,153,8,23,202,1,23,207,1,28,248,22,153, 7,23,203,2,249,22,168,8,23,204,1,8,63,23,202,1,28,248,22,133,4, -248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2, -70,200,192,28,248,22,175,15,196,248,22,176,15,196,247,22,177,15,28,248,22, +248,22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2, +70,200,192,28,248,22,176,15,196,248,22,177,15,196,247,22,178,15,28,248,22, 133,4,23,197,2,86,94,23,196,1,19,248,22,147,8,23,195,2,19,248,22, -147,8,23,196,2,249,22,184,15,27,251,22,154,8,250,22,153,8,23,205,2, +147,8,23,196,2,249,22,185,15,27,251,22,154,8,250,22,153,8,23,205,2, 39,23,204,4,2,51,249,22,153,8,23,204,1,23,202,4,28,248,22,153,7, 23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28,248,22,133,4,248, -22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2,37,2,69,2,70, -202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177,15,2,2,27,248, +22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2,37,2,69,2,70, +202,192,28,248,22,176,15,198,248,22,177,15,198,247,22,178,15,2,2,27,248, 22,182,3,23,198,1,28,249,22,169,9,8,46,249,22,148,8,23,198,2,23, -197,2,27,248,22,181,3,23,195,2,249,22,184,15,27,251,22,154,8,250,22, +197,2,27,248,22,181,3,23,195,2,249,22,185,15,27,251,22,154,8,250,22, 153,8,23,205,2,39,23,204,1,2,71,249,22,153,8,23,204,1,23,202,1, 28,248,22,153,7,23,205,2,249,22,168,8,23,206,1,8,63,23,204,1,28, -248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,183,11,2, -37,2,69,2,70,202,192,28,248,22,175,15,198,248,22,176,15,198,247,22,177, +248,22,133,4,248,22,147,8,23,195,2,86,94,23,193,1,251,22,184,11,2, +37,2,69,2,70,202,192,28,248,22,176,15,198,248,22,177,15,198,247,22,178, 15,28,248,22,133,4,193,253,2,175,2,199,200,201,248,22,147,8,200,2,51, 248,22,147,8,200,27,248,22,182,3,194,28,249,22,169,9,8,46,249,22,148, 8,198,196,253,2,175,2,200,201,202,198,2,71,248,22,181,3,199,251,2,174, -2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,175, -15,23,196,2,10,28,248,22,174,15,23,196,2,10,28,248,22,153,7,23,196, -2,28,248,22,133,16,23,196,2,10,248,22,134,16,23,196,2,11,12,252,22, -181,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7,23,197, -2,10,248,22,142,8,23,197,2,12,252,22,181,11,2,37,2,72,40,23,200, -2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,199,2,86, -94,23,195,1,86,94,28,192,12,250,22,184,11,2,37,2,73,23,201,2,249, -22,7,194,195,27,248,22,180,15,23,196,1,27,251,2,174,2,23,198,2,23, -201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,175,15,195,249,22,128, +2,198,199,200,196,90,144,41,11,89,146,41,39,11,86,95,28,28,248,22,176, +15,23,196,2,10,28,248,22,175,15,23,196,2,10,28,248,22,153,7,23,196, +2,28,248,22,134,16,23,196,2,10,248,22,135,16,23,196,2,11,12,252,22, +182,11,2,37,2,42,39,23,200,2,23,201,2,28,28,248,22,153,7,23,197, +2,10,248,22,142,8,23,197,2,12,252,22,182,11,2,37,2,72,40,23,200, +2,23,201,2,90,144,42,11,89,146,42,39,11,248,22,132,16,23,199,2,86, +94,23,195,1,86,94,28,192,12,250,22,185,11,2,37,2,73,23,201,2,249, +22,7,194,195,27,248,22,181,15,23,196,1,27,251,2,174,2,23,198,2,23, +201,1,23,202,1,248,22,147,8,23,199,1,28,248,22,176,15,195,249,22,129, 16,196,194,192,252,80,144,44,8,35,42,2,37,2,71,22,153,8,198,199,249, 247,22,176,5,23,195,1,11,249,247,22,176,5,194,11,28,248,22,88,23,195, -2,9,27,27,248,22,81,23,197,2,28,248,22,135,16,23,194,2,248,22,138, -16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11, -248,22,131,16,249,22,136,16,250,80,144,50,43,42,248,22,151,16,2,56,11, -11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22, -136,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,151,16,2,56, -23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11,28,23,193,2,249, -22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,27,248,22,164, +2,9,27,27,248,22,81,23,197,2,28,248,22,136,16,23,194,2,248,22,139, +16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11,89,146,42,39,11, +248,22,132,16,249,22,137,16,250,80,144,50,43,42,248,22,152,16,2,56,11, +11,248,22,152,16,2,57,86,95,23,195,1,23,194,1,248,22,139,16,249,22, +137,16,23,199,1,23,196,1,27,250,80,144,45,43,42,248,22,152,16,2,56, +23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11,28,23,193,2,249, +22,80,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,27,248,22,165, 20,23,199,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22, -81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198, -1,247,22,152,16,248,80,144,47,8,50,42,248,22,164,20,23,198,1,86,94, -23,193,1,248,80,144,45,8,50,42,248,22,164,20,23,196,1,86,94,23,193, -1,27,248,22,164,20,23,197,1,28,248,22,88,23,194,2,9,27,248,80,144, -43,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249, -22,136,16,23,198,1,247,22,152,16,248,80,144,45,8,50,42,248,22,164,20, -23,198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,164,20,23,196, -1,28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,135, -16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144, -42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,50,43,42, -248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194, -1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,45,43, -42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194, -1,11,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247, -22,152,16,27,248,22,164,20,23,199,1,28,248,22,88,23,194,2,9,27,248, -80,144,45,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,138, -16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,47,8,51,42,248,22, -164,20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,164,20, -23,196,1,86,94,23,193,1,27,248,22,164,20,23,197,1,28,248,22,88,23, +81,23,196,2,28,23,193,2,249,22,80,248,22,139,16,249,22,137,16,23,198, +1,247,22,153,16,248,80,144,47,8,50,42,248,22,165,20,23,198,1,86,94, +23,193,1,248,80,144,45,8,50,42,248,22,165,20,23,196,1,86,94,23,193, +1,27,248,22,165,20,23,197,1,28,248,22,88,23,194,2,9,27,248,80,144, +43,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,139,16,249, +22,137,16,23,198,1,247,22,153,16,248,80,144,45,8,50,42,248,22,165,20, +23,198,1,86,94,23,193,1,248,80,144,43,8,50,42,248,22,165,20,23,196, +1,28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,136, +16,23,194,2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2,90,144, +42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,50,43,42, +248,22,152,16,2,56,11,11,248,22,152,16,2,57,86,95,23,195,1,23,194, +1,248,22,139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144,45,43, +42,248,22,152,16,2,56,23,197,1,10,28,23,193,2,248,22,139,16,23,194, +1,11,28,23,193,2,249,22,80,248,22,139,16,249,22,137,16,23,198,1,247, +22,153,16,27,248,22,165,20,23,199,1,28,248,22,88,23,194,2,9,27,248, +80,144,45,56,42,248,22,81,23,196,2,28,23,193,2,249,22,80,248,22,139, +16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,47,8,51,42,248,22, +165,20,23,198,1,86,94,23,193,1,248,80,144,45,8,51,42,248,22,165,20, +23,196,1,86,94,23,193,1,27,248,22,165,20,23,197,1,28,248,22,88,23, 194,2,9,27,248,80,144,43,56,42,248,22,81,23,196,2,28,23,193,2,249, -22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,45, -8,51,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51, -42,248,22,164,20,23,196,1,27,248,22,151,16,2,58,28,248,22,135,16,23, -194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42,11, -89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,49,43,42,248,22, -151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1,248, -22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248, -22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1,11, -28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,135,16, -23,194,2,248,22,138,16,23,194,1,28,248,22,134,16,23,194,2,90,144,42, -11,89,146,42,39,11,248,22,131,16,249,22,136,16,250,80,144,50,43,42,248, -22,151,16,2,56,11,11,248,22,151,16,2,57,86,95,23,195,1,23,194,1, -248,22,138,16,249,22,136,16,23,199,1,23,196,1,27,250,80,144,45,43,42, -248,22,151,16,2,56,23,197,1,10,28,23,193,2,248,22,138,16,23,194,1, -11,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22, -152,16,27,248,22,164,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248, -22,81,23,196,2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28, -248,22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249, -22,136,16,250,80,144,54,43,42,248,22,151,16,2,56,11,11,248,22,151,16, -2,57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1, -23,196,1,27,250,80,144,49,43,42,248,22,151,16,2,56,23,197,1,10,28, -23,193,2,248,22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138, -16,249,22,136,16,23,198,1,247,22,152,16,27,248,22,164,20,23,198,1,28, +22,80,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,45, +8,51,42,248,22,165,20,23,198,1,86,94,23,193,1,248,80,144,43,8,51, +42,248,22,165,20,23,196,1,27,248,22,152,16,2,58,28,248,22,136,16,23, +194,2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2,90,144,42,11, +89,146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,49,43,42,248,22, +152,16,2,56,11,11,248,22,152,16,2,57,86,95,23,195,1,23,194,1,248, +22,139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144,44,43,42,248, +22,152,16,2,56,23,197,1,10,28,23,193,2,248,22,139,16,23,194,1,11, +28,248,22,88,23,195,2,9,27,27,248,22,81,23,197,2,28,248,22,136,16, +23,194,2,248,22,139,16,23,194,1,28,248,22,135,16,23,194,2,90,144,42, +11,89,146,42,39,11,248,22,132,16,249,22,137,16,250,80,144,50,43,42,248, +22,152,16,2,56,11,11,248,22,152,16,2,57,86,95,23,195,1,23,194,1, +248,22,139,16,249,22,137,16,23,199,1,23,196,1,27,250,80,144,45,43,42, +248,22,152,16,2,56,23,197,1,10,28,23,193,2,248,22,139,16,23,194,1, +11,28,23,193,2,249,22,80,248,22,139,16,249,22,137,16,23,198,1,247,22, +153,16,27,248,22,165,20,23,199,1,28,248,22,88,23,194,2,9,27,27,248, +22,81,23,196,2,28,248,22,136,16,23,194,2,248,22,139,16,23,194,1,28, +248,22,135,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249, +22,137,16,250,80,144,54,43,42,248,22,152,16,2,56,11,11,248,22,152,16, +2,57,86,95,23,195,1,23,194,1,248,22,139,16,249,22,137,16,23,199,1, +23,196,1,27,250,80,144,49,43,42,248,22,152,16,2,56,23,197,1,10,28, +23,193,2,248,22,139,16,23,194,1,11,28,23,193,2,249,22,80,248,22,139, +16,249,22,137,16,23,198,1,247,22,153,16,27,248,22,165,20,23,198,1,28, 248,22,88,23,194,2,9,27,248,80,144,49,56,42,248,22,81,23,196,2,28, -23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16, -248,80,144,51,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80, -144,49,8,53,42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164, +23,193,2,249,22,80,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16, +248,80,144,51,8,53,42,248,22,165,20,23,198,1,86,94,23,193,1,248,80, +144,49,8,53,42,248,22,165,20,23,196,1,86,94,23,193,1,27,248,22,165, 20,23,196,1,28,248,22,88,23,194,2,9,27,248,80,144,47,56,42,248,22, -81,23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198, -1,247,22,152,16,248,80,144,49,8,53,42,248,22,164,20,23,198,1,86,94, -23,193,1,248,80,144,47,8,53,42,248,22,164,20,23,196,1,86,94,23,193, -1,27,248,22,164,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22, -81,23,196,2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248, -22,134,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22, -136,16,250,80,144,52,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2, -57,86,95,23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23, -196,1,27,250,80,144,47,43,42,248,22,151,16,2,56,23,197,1,10,28,23, -193,2,248,22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16, -249,22,136,16,23,198,1,247,22,152,16,27,248,22,164,20,23,198,1,28,248, +81,23,196,2,28,23,193,2,249,22,80,248,22,139,16,249,22,137,16,23,198, +1,247,22,153,16,248,80,144,49,8,53,42,248,22,165,20,23,198,1,86,94, +23,193,1,248,80,144,47,8,53,42,248,22,165,20,23,196,1,86,94,23,193, +1,27,248,22,165,20,23,197,1,28,248,22,88,23,194,2,9,27,27,248,22, +81,23,196,2,28,248,22,136,16,23,194,2,248,22,139,16,23,194,1,28,248, +22,135,16,23,194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249,22, +137,16,250,80,144,52,43,42,248,22,152,16,2,56,11,11,248,22,152,16,2, +57,86,95,23,195,1,23,194,1,248,22,139,16,249,22,137,16,23,199,1,23, +196,1,27,250,80,144,47,43,42,248,22,152,16,2,56,23,197,1,10,28,23, +193,2,248,22,139,16,23,194,1,11,28,23,193,2,249,22,80,248,22,139,16, +249,22,137,16,23,198,1,247,22,153,16,27,248,22,165,20,23,198,1,28,248, 22,88,23,194,2,9,27,248,80,144,47,56,42,248,22,81,23,196,2,28,23, -193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248, -80,144,49,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144, -47,8,53,42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164,20, +193,2,249,22,80,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,248, +80,144,49,8,53,42,248,22,165,20,23,198,1,86,94,23,193,1,248,80,144, +47,8,53,42,248,22,165,20,23,196,1,86,94,23,193,1,27,248,22,165,20, 23,196,1,28,248,22,88,23,194,2,9,27,248,80,144,45,56,42,248,22,81, -23,196,2,28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1, -247,22,152,16,248,80,144,47,8,53,42,248,22,164,20,23,198,1,86,94,23, -193,1,248,80,144,45,8,53,42,248,22,164,20,23,196,1,27,247,22,159,16, +23,196,2,28,23,193,2,249,22,80,248,22,139,16,249,22,137,16,23,198,1, +247,22,153,16,248,80,144,47,8,53,42,248,22,165,20,23,198,1,86,94,23, +193,1,248,80,144,45,8,53,42,248,22,165,20,23,196,1,27,247,22,160,16, 27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43,44,41,28,23, 196,2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7, 63,2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200, -1,250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247, +1,250,22,129,16,248,22,152,16,2,61,250,22,158,2,23,205,1,2,59,247, 22,171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8,50,42,250,22, -94,9,248,22,90,248,22,151,16,2,55,9,28,193,249,22,80,195,194,192,27, -247,22,159,16,27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43, +94,9,248,22,90,248,22,152,16,2,55,9,28,193,249,22,80,195,194,192,27, +247,22,160,16,27,248,80,144,42,58,42,247,80,144,42,57,42,249,80,144,43, 44,41,28,23,196,2,27,249,22,175,8,247,22,174,8,2,75,28,192,249,22, 165,8,194,7,63,2,66,2,66,250,80,144,46,8,23,42,23,198,2,2,76, -27,28,23,200,1,250,22,128,16,248,22,151,16,2,61,250,22,158,2,23,205, +27,28,23,200,1,250,22,129,16,248,22,152,16,2,61,250,22,158,2,23,205, 1,2,59,247,22,171,8,2,77,86,94,23,199,1,11,27,248,80,144,49,8, -51,42,250,22,94,23,207,1,248,22,90,248,22,151,16,2,55,9,28,193,249, -22,80,195,194,192,27,247,22,159,16,27,248,80,144,42,58,42,249,80,144,44, +51,42,250,22,94,23,207,1,248,22,90,248,22,152,16,2,55,9,28,193,249, +22,80,195,194,192,27,247,22,160,16,27,248,80,144,42,58,42,249,80,144,44, 55,40,40,80,144,44,8,52,42,249,80,144,43,44,41,28,23,196,2,27,249, 22,175,8,247,22,174,8,2,75,28,192,249,22,165,8,194,7,63,2,66,2, -66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1,250,22,128, -16,248,22,151,16,2,61,250,22,158,2,23,205,1,2,59,247,22,171,8,2, -77,86,94,23,199,1,11,27,27,250,22,94,23,207,1,248,22,90,248,22,151, +66,250,80,144,46,8,23,42,23,198,2,2,76,27,28,23,200,1,250,22,129, +16,248,22,152,16,2,61,250,22,158,2,23,205,1,2,59,247,22,171,8,2, +77,86,94,23,199,1,11,27,27,250,22,94,23,207,1,248,22,90,248,22,152, 16,2,55,23,208,1,28,248,22,88,23,194,2,9,27,27,248,22,81,23,196, -2,28,248,22,135,16,23,194,2,248,22,138,16,23,194,1,28,248,22,134,16, -23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,249,22,136,16,250, -80,144,60,43,42,248,22,151,16,2,56,11,11,248,22,151,16,2,57,86,95, -23,195,1,23,194,1,248,22,138,16,249,22,136,16,23,199,1,23,196,1,27, -250,80,144,55,43,42,248,22,151,16,2,56,23,197,1,10,28,23,193,2,248, -22,138,16,23,194,1,11,28,23,193,2,249,22,80,248,22,138,16,249,22,136, -16,23,198,1,247,22,152,16,27,248,22,164,20,23,198,1,28,248,22,88,23, +2,28,248,22,136,16,23,194,2,248,22,139,16,23,194,1,28,248,22,135,16, +23,194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,249,22,137,16,250, +80,144,60,43,42,248,22,152,16,2,56,11,11,248,22,152,16,2,57,86,95, +23,195,1,23,194,1,248,22,139,16,249,22,137,16,23,199,1,23,196,1,27, +250,80,144,55,43,42,248,22,152,16,2,56,23,197,1,10,28,23,193,2,248, +22,139,16,23,194,1,11,28,23,193,2,249,22,80,248,22,139,16,249,22,137, +16,23,198,1,247,22,153,16,27,248,22,165,20,23,198,1,28,248,22,88,23, 194,2,9,27,248,80,144,55,56,42,248,22,81,23,196,2,28,23,193,2,249, -22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152,16,248,80,144,57, -8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53, -42,248,22,164,20,23,196,1,86,94,23,193,1,27,248,22,164,20,23,196,1, +22,80,248,22,139,16,249,22,137,16,23,198,1,247,22,153,16,248,80,144,57, +8,53,42,248,22,165,20,23,198,1,86,94,23,193,1,248,80,144,55,8,53, +42,248,22,165,20,23,196,1,86,94,23,193,1,27,248,22,165,20,23,196,1, 28,248,22,88,23,194,2,9,27,248,80,144,53,56,42,248,22,81,23,196,2, -28,23,193,2,249,22,80,248,22,138,16,249,22,136,16,23,198,1,247,22,152, -16,248,80,144,55,8,53,42,248,22,164,20,23,198,1,86,94,23,193,1,248, -80,144,53,8,53,42,248,22,164,20,23,196,1,28,193,249,22,80,195,194,192, +28,23,193,2,249,22,80,248,22,139,16,249,22,137,16,23,198,1,247,22,153, +16,248,80,144,55,8,53,42,248,22,165,20,23,198,1,86,94,23,193,1,248, +80,144,53,8,53,42,248,22,165,20,23,196,1,28,193,249,22,80,195,194,192, 27,20,13,144,80,144,40,46,40,26,9,80,144,49,47,40,249,22,31,11,80, -144,51,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157,15,10,248, +144,51,46,40,22,149,15,10,22,156,15,10,22,157,15,10,22,158,15,10,248, 22,148,6,23,196,2,28,248,22,148,7,23,194,2,12,86,94,248,22,177,9, 23,194,1,27,20,13,144,80,144,41,46,40,26,9,80,144,50,47,40,249,22, -31,11,80,144,52,46,40,22,148,15,10,22,155,15,10,22,156,15,10,22,157, +31,11,80,144,52,46,40,22,149,15,10,22,156,15,10,22,157,15,10,22,158, 15,10,248,22,148,6,23,197,2,28,248,22,148,7,23,194,2,12,86,94,248, 22,177,9,23,194,1,27,20,13,144,80,144,42,46,40,26,9,80,144,51,47, -40,249,22,31,11,80,144,53,46,40,22,148,15,10,22,155,15,10,22,156,15, -10,22,157,15,10,248,22,148,6,23,198,2,28,248,22,148,7,23,194,2,12, +40,249,22,31,11,80,144,53,46,40,22,149,15,10,22,156,15,10,22,157,15, +10,22,158,15,10,248,22,148,6,23,198,2,28,248,22,148,7,23,194,2,12, 86,94,248,22,177,9,23,194,1,248,80,144,43,8,54,42,197,86,94,249,22, 139,7,247,22,172,5,23,196,2,248,22,163,6,249,22,136,4,39,249,22,184, 3,28,23,198,2,23,198,1,86,94,23,198,1,39,23,199,1,27,248,22,189, 5,28,23,198,2,86,95,23,197,1,23,196,1,23,198,1,86,94,23,198,1, -27,250,80,144,45,43,42,248,22,151,16,2,56,11,11,27,248,22,139,4,23, +27,250,80,144,45,43,42,248,22,152,16,2,56,11,11,27,248,22,139,4,23, 199,1,27,28,23,194,2,23,194,1,86,94,23,194,1,39,27,248,22,139,4, 23,202,1,249,22,140,6,23,198,1,20,20,95,88,148,8,36,39,51,11,9, 224,3,2,33,190,2,23,195,1,23,196,1,248,80,144,41,8,54,42,193,144, @@ -973,7 +973,7 @@ 41,40,20,15,16,2,88,148,8,36,41,61,41,2,6,223,0,33,85,80,144, 39,42,40,20,15,16,2,20,26,96,2,7,88,148,8,36,42,8,24,8,32, 9,223,0,33,92,88,148,8,36,41,50,55,9,223,0,33,93,88,148,8,36, -40,49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,163, +40,49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,164, 16,248,22,167,8,27,28,249,22,169,9,247,22,180,8,2,43,6,1,1,59, 6,1,1,58,250,22,137,8,6,14,14,40,91,94,126,97,93,42,41,126,97, 40,46,42,41,23,196,2,23,196,1,88,148,8,36,41,51,11,2,8,223,0, @@ -1046,7 +1046,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 19760); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,8, 0,23,0,48,0,65,0,83,0,105,0,128,0,149,0,171,0,180,0,189,0, 196,0,205,0,212,0,0,0,247,1,0,0,3,1,5,105,110,115,112,48,76, @@ -1066,7 +1066,7 @@ 39,16,2,2,6,2,7,41,11,11,11,16,5,2,4,2,8,2,9,2,5, 2,3,16,5,11,11,11,11,11,16,5,2,4,2,8,2,9,2,5,2,3, 44,44,40,12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16, -0,16,0,39,39,16,3,20,15,16,6,253,22,189,10,2,4,11,41,39,11, +0,16,0,39,39,16,3,20,15,16,6,253,22,190,10,2,4,11,41,39,11, 248,22,90,249,22,80,22,175,10,88,148,39,40,48,47,9,223,9,33,10,80, 144,39,39,40,80,144,39,40,40,80,144,39,41,40,80,144,39,42,40,80,144, 39,43,40,20,15,16,2,20,28,143,88,148,39,40,48,47,9,223,0,33,11, @@ -1077,7 +1077,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 578); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,1,0,0,8, 0,15,0,26,0,53,0,59,0,73,0,86,0,112,0,129,0,151,0,159,0, 171,0,186,0,202,0,220,0,241,0,253,0,13,1,36,1,60,1,72,1,103, @@ -1112,65 +1112,65 @@ 6,12,12,109,111,100,117,108,101,45,112,97,116,104,63,68,115,117,98,109,111, 100,6,2,2,46,46,6,1,1,46,66,102,105,108,101,68,112,108,97,110,101, 116,6,8,8,109,97,105,110,46,114,107,116,6,4,4,46,114,107,116,69,105, -103,110,111,114,101,100,27,252,22,128,16,28,249,22,169,9,23,201,2,2,27, -86,94,23,199,1,23,200,1,28,248,22,133,16,23,200,2,249,22,128,16,23, +103,110,111,114,101,100,27,252,22,129,16,28,249,22,169,9,23,201,2,2,27, +86,94,23,199,1,23,200,1,28,248,22,134,16,23,200,2,249,22,129,16,23, 202,1,23,201,1,249,80,144,50,45,42,23,202,1,23,201,1,23,203,1,2, 28,247,22,181,8,249,80,144,50,46,42,23,203,1,80,144,50,39,41,27,250, -22,146,16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22, +22,147,16,196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22, 80,195,194,11,249,22,5,20,20,96,88,148,8,36,40,57,8,129,3,9,226, 5,4,3,6,33,42,23,199,1,23,196,1,23,197,1,23,195,1,27,252,22, -128,16,28,249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28, -248,22,133,16,23,200,2,249,22,128,16,23,202,1,23,201,1,249,80,144,50, +129,16,28,249,22,169,9,23,201,2,2,27,86,94,23,199,1,23,200,1,28, +248,22,134,16,23,200,2,249,22,129,16,23,202,1,23,201,1,249,80,144,50, 45,42,23,202,1,23,201,1,23,203,1,2,28,247,22,181,8,249,80,144,50, -46,42,23,203,1,80,144,50,39,41,27,250,22,146,16,196,11,32,0,88,148, +46,42,23,203,1,80,144,50,39,41,27,250,22,147,16,196,11,32,0,88,148, 8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22,5,20,20, 96,88,148,8,36,40,57,8,129,3,9,226,5,4,3,6,33,44,23,199,1, -23,196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169,9,23,199, -2,2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198,2,249,22, -128,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23, -201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16,196,11,32, +23,196,1,23,197,1,23,195,1,27,250,22,129,16,28,249,22,169,9,23,199, +2,2,27,86,94,23,197,1,23,198,1,28,248,22,134,16,23,198,2,249,22, +129,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23,199,1,23, +201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,147,16,196,11,32, 0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194,11,249,22, 5,20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3,6,33,46, -23,199,1,23,196,1,23,197,1,23,195,1,27,250,22,128,16,28,249,22,169, -9,23,199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,133,16,23,198, -2,249,22,128,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23, -199,1,23,201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,146,16, +23,199,1,23,196,1,23,197,1,23,195,1,27,250,22,129,16,28,249,22,169, +9,23,199,2,2,27,86,94,23,197,1,23,198,1,28,248,22,134,16,23,198, +2,249,22,129,16,23,200,1,23,199,1,249,80,144,48,45,42,23,200,1,23, +199,1,23,201,1,249,80,144,48,46,42,23,201,1,2,29,27,250,22,147,16, 196,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249,22,80,195,194, 11,249,22,5,20,20,96,88,148,8,36,40,55,8,128,3,9,226,5,4,3, 6,33,48,23,199,1,23,196,1,23,197,1,23,195,1,86,95,28,248,80,144, -40,43,42,23,195,2,12,250,22,181,11,2,25,6,12,12,112,97,116,104,45, +40,43,42,23,195,2,12,250,22,182,11,2,25,6,12,12,112,97,116,104,45, 115,116,114,105,110,103,63,23,197,2,28,28,23,195,2,28,248,22,64,23,196, 2,10,28,248,22,89,23,196,2,28,249,22,130,4,248,22,93,23,198,2,40, -28,28,248,22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,163,20,23, -197,2,249,22,4,22,64,248,22,164,20,23,198,2,11,11,11,10,12,250,22, -181,11,2,25,6,71,71,40,111,114,47,99,32,35,102,32,115,121,109,98,111, +28,28,248,22,64,248,22,81,23,197,2,10,248,22,167,9,248,22,164,20,23, +197,2,249,22,4,22,64,248,22,165,20,23,198,2,11,11,11,10,12,250,22, +182,11,2,25,6,71,71,40,111,114,47,99,32,35,102,32,115,121,109,98,111, 108,63,32,40,99,111,110,115,47,99,32,40,111,114,47,99,32,35,102,32,115, 121,109,98,111,108,63,41,32,40,110,111,110,45,101,109,112,116,121,45,108,105, 115,116,111,102,32,115,121,109,98,111,108,63,41,41,41,23,197,2,27,28,23, 196,2,247,22,191,4,11,27,28,23,194,2,250,22,158,2,80,143,44,44,248, -22,128,17,247,22,144,14,11,11,27,28,23,194,2,250,22,158,2,248,22,82, +22,129,17,247,22,145,14,11,11,27,28,23,194,2,250,22,158,2,248,22,82, 23,198,2,23,198,2,11,11,28,23,193,2,86,96,23,197,1,23,195,1,23, 194,1,20,13,144,80,144,42,41,40,250,80,144,45,42,40,249,22,31,11,80, 144,47,41,40,22,128,5,248,22,102,23,197,2,27,248,22,111,23,195,2,20, 13,144,80,144,43,41,40,250,80,144,46,42,40,249,22,31,11,80,144,48,41, -40,22,177,5,28,248,22,174,15,23,197,2,23,196,1,86,94,23,196,1,247, -22,152,16,249,247,22,175,5,248,22,163,20,23,197,1,23,201,1,86,94,23, -193,1,27,28,248,22,135,16,23,199,2,23,198,2,27,247,22,177,5,28,192, -249,22,136,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248, -22,131,16,23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28, -23,204,2,27,248,22,179,15,23,198,2,19,248,22,147,8,194,28,28,249,22, +40,22,177,5,28,248,22,175,15,23,197,2,23,196,1,86,94,23,196,1,247, +22,153,16,249,247,22,175,5,248,22,164,20,23,197,1,23,201,1,86,94,23, +193,1,27,28,248,22,136,16,23,199,2,23,198,2,27,247,22,177,5,28,192, +249,22,137,16,23,201,2,194,23,199,2,90,144,42,11,89,146,42,39,11,248, +22,132,16,23,202,1,86,94,23,195,1,90,144,41,11,89,146,41,39,11,28, +23,204,2,27,248,22,180,15,23,198,2,19,248,22,147,8,194,28,28,249,22, 132,4,23,195,4,43,249,22,150,8,2,26,249,22,153,8,197,249,22,184,3, -23,199,4,43,11,249,22,7,23,200,2,248,22,183,15,249,22,154,8,250,22, +23,199,4,43,11,249,22,7,23,200,2,248,22,184,15,249,22,154,8,250,22, 153,8,201,39,249,22,184,3,23,203,4,43,5,3,46,115,115,249,22,7,23, 200,2,11,2,249,22,7,23,198,2,11,27,28,249,22,169,9,23,196,2,23, -199,2,23,199,2,249,22,128,16,23,198,2,23,196,2,27,28,23,196,2,28, -249,22,169,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,128, +199,2,23,199,2,249,22,129,16,23,198,2,23,196,2,27,28,23,196,2,28, +249,22,169,9,23,198,2,23,200,1,23,200,1,86,94,23,200,1,249,22,129, 16,23,199,2,23,198,2,86,94,23,198,1,11,27,28,249,22,169,9,23,200, 2,70,114,101,108,97,116,105,118,101,86,94,23,198,1,2,27,23,198,1,27, -247,22,157,16,27,247,22,158,16,27,250,22,146,16,23,201,2,11,32,0,88, +247,22,158,16,27,247,22,159,16,27,250,22,147,16,23,201,2,11,32,0,88, 148,8,36,39,44,11,9,222,11,27,28,23,194,2,249,22,80,23,201,2,23, 196,1,86,94,23,194,1,11,27,28,23,199,2,28,23,194,2,11,27,250,22, -146,16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249, +147,16,23,203,2,11,32,0,88,148,8,36,39,44,11,9,222,11,28,192,249, 22,80,23,202,2,194,11,11,27,28,23,195,2,23,195,2,23,194,2,27,28, 23,196,2,23,196,2,248,22,167,9,23,196,2,27,28,23,205,2,28,23,196, 2,86,94,23,197,1,23,196,2,248,22,167,9,23,198,1,11,27,28,23,195, @@ -1181,8 +1181,8 @@ 23,201,1,23,200,1,23,197,1,23,196,1,23,195,1,23,194,1,20,13,144, 80,144,60,41,40,250,80,144,8,24,42,40,249,22,31,11,80,144,8,26,41, 40,22,128,5,11,20,13,144,80,144,60,41,40,250,80,144,8,24,42,40,249, -22,31,11,80,144,8,26,41,40,22,177,5,28,248,22,174,15,23,206,2,23, -205,1,86,94,23,205,1,247,22,152,16,249,247,22,162,16,248,22,81,23,196, +22,31,11,80,144,8,26,41,40,22,177,5,28,248,22,175,15,23,206,2,23, +205,1,86,94,23,205,1,247,22,153,16,249,247,22,163,16,248,22,81,23,196, 1,23,218,1,86,94,23,193,1,27,28,23,195,2,27,249,22,5,88,148,39, 40,51,8,129,3,9,226,25,17,13,12,33,45,23,204,2,27,28,23,200,2, 11,193,28,192,192,28,193,28,199,28,249,22,132,4,248,22,82,196,248,22,82, @@ -1190,8 +1190,8 @@ 23,206,1,23,205,1,23,202,1,23,201,1,23,197,1,23,196,1,23,195,1, 20,13,144,80,144,61,41,40,250,80,144,8,25,42,40,249,22,31,11,80,144, 8,27,41,40,22,128,5,23,207,1,20,13,144,80,144,61,41,40,250,80,144, -8,25,42,40,249,22,31,11,80,144,8,27,41,40,22,177,5,28,248,22,174, -15,23,207,2,23,206,1,86,94,23,206,1,247,22,152,16,249,247,22,162,16, +8,25,42,40,249,22,31,11,80,144,8,27,41,40,22,177,5,28,248,22,175, +15,23,207,2,23,206,1,86,94,23,206,1,247,22,153,16,249,247,22,163,16, 248,22,81,23,196,1,23,219,1,86,94,23,193,1,27,28,23,197,2,27,249, 22,5,20,20,94,88,148,39,40,51,8,128,3,9,226,26,17,14,13,33,47, 23,210,1,23,205,2,27,28,23,200,2,11,193,28,192,192,28,193,28,23,200, @@ -1202,8 +1202,8 @@ 90,23,199,1,11,23,211,2,12,20,13,144,80,144,8,23,41,40,250,80,144, 8,26,42,40,249,22,31,11,80,144,8,28,41,40,22,128,5,11,20,13,144, 80,144,8,23,41,40,250,80,144,8,26,42,40,249,22,31,11,80,144,8,28, -41,40,22,177,5,28,248,22,174,15,23,208,2,23,207,1,86,94,23,207,1, -247,22,152,16,249,247,22,175,5,248,22,163,20,23,196,1,23,220,1,86,94, +41,40,22,177,5,28,248,22,175,15,23,208,2,23,207,1,86,94,23,207,1, +247,22,153,16,249,247,22,175,5,248,22,164,20,23,196,1,23,220,1,86,94, 23,193,1,27,28,23,197,1,27,249,22,5,20,20,95,88,148,39,40,51,8, 128,3,9,226,27,19,15,14,33,49,23,207,1,23,212,1,23,206,1,27,28, 23,201,2,11,193,28,192,192,28,193,28,200,28,249,22,132,4,248,22,82,196, @@ -1213,16 +1213,16 @@ 1,23,213,2,23,212,2,12,20,13,144,80,144,8,24,41,40,250,80,144,8, 27,42,40,249,22,31,11,80,144,8,29,41,40,22,128,5,23,209,1,20,13, 144,80,144,8,24,41,40,250,80,144,8,27,42,40,249,22,31,11,80,144,8, -29,41,40,22,177,5,28,248,22,174,15,23,209,2,23,208,1,86,94,23,208, -1,247,22,152,16,249,247,22,175,5,248,22,163,20,23,196,1,23,221,1,86, -94,23,193,1,28,28,248,22,78,23,220,2,248,22,163,20,23,220,2,10,27, +29,41,40,22,177,5,28,248,22,175,15,23,209,2,23,208,1,86,94,23,208, +1,247,22,153,16,249,247,22,175,5,248,22,164,20,23,196,1,23,221,1,86, +94,23,193,1,28,28,248,22,78,23,220,2,248,22,164,20,23,220,2,10,27, 28,23,199,2,86,94,23,207,1,23,208,1,86,94,23,208,1,23,207,1,28, -28,248,22,78,23,221,2,248,22,167,9,248,22,186,15,23,195,2,11,12,20, +28,248,22,78,23,221,2,248,22,167,9,248,22,187,15,23,195,2,11,12,20, 13,144,80,144,8,25,41,40,250,80,144,8,28,42,40,249,22,31,11,80,144, 8,30,41,40,22,128,5,28,23,223,2,28,23,202,1,11,23,196,2,86,94, 23,202,1,11,20,13,144,80,144,8,25,41,40,250,80,144,8,28,42,40,249, -22,31,11,80,144,8,30,41,40,22,177,5,28,248,22,174,15,23,210,2,23, -209,1,86,94,23,209,1,247,22,152,16,249,247,22,175,5,23,195,1,23,222, +22,31,11,80,144,8,30,41,40,22,177,5,28,248,22,175,15,23,210,2,23, +209,1,86,94,23,209,1,247,22,153,16,249,247,22,175,5,23,195,1,23,222, 1,12,28,23,194,2,250,22,156,2,248,22,82,23,198,1,23,196,1,250,22, 90,23,201,1,23,202,1,23,203,1,12,27,249,22,189,8,80,144,42,50,41, 249,22,191,3,248,22,187,3,248,22,173,2,200,8,128,8,27,28,193,248,22, @@ -1286,22 +1286,22 @@ 7,23,200,2,39,23,198,2,248,2,56,249,22,175,7,23,200,1,248,22,181, 3,23,199,1,250,2,54,23,197,4,197,248,22,181,3,196,32,70,88,148,39, 40,58,11,2,31,222,33,71,28,248,22,88,248,22,82,23,195,2,249,22,7, -9,248,22,163,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,164, -20,23,197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,163, -20,195,90,144,41,11,89,146,41,39,11,27,248,22,164,20,196,28,248,22,88, -248,22,82,23,195,2,249,22,7,9,248,22,163,20,195,90,144,41,11,89,146, -41,39,11,248,2,70,248,22,164,20,196,249,22,7,249,22,80,248,22,163,20, -199,196,195,249,22,7,249,22,80,248,22,163,20,199,196,195,249,22,7,249,22, -80,248,22,163,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23, +9,248,22,164,20,23,196,1,90,144,41,11,89,146,41,39,11,27,248,22,165, +20,23,197,2,28,248,22,88,248,22,82,23,195,2,249,22,7,9,248,22,164, +20,195,90,144,41,11,89,146,41,39,11,27,248,22,165,20,196,28,248,22,88, +248,22,82,23,195,2,249,22,7,9,248,22,164,20,195,90,144,41,11,89,146, +41,39,11,248,2,70,248,22,165,20,196,249,22,7,249,22,80,248,22,164,20, +199,196,195,249,22,7,249,22,80,248,22,164,20,199,196,195,249,22,7,249,22, +80,248,22,164,20,23,200,1,23,197,1,23,196,1,27,19,248,22,156,7,23, 196,2,250,2,54,23,196,4,23,198,1,39,2,28,23,195,1,192,28,248,22, -88,248,22,82,23,195,2,249,22,7,9,248,22,163,20,23,196,1,27,248,22, -164,20,23,195,2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82, -23,197,2,249,22,7,9,248,22,163,20,23,198,1,27,248,22,164,20,23,197, +88,248,22,82,23,195,2,249,22,7,9,248,22,164,20,23,196,1,27,248,22, +165,20,23,195,2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82, +23,197,2,249,22,7,9,248,22,164,20,23,198,1,27,248,22,165,20,23,197, 2,90,144,41,11,89,146,41,39,11,28,248,22,88,248,22,82,23,197,2,249, -22,7,9,248,22,163,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248, -22,164,20,198,249,22,7,249,22,80,248,22,163,20,201,196,195,249,22,7,249, -22,80,248,22,163,20,23,203,1,196,195,249,22,7,249,22,80,248,22,163,20, -23,201,1,23,197,1,23,196,1,248,22,143,12,252,22,162,10,248,22,163,4, +22,7,9,248,22,164,20,197,90,144,41,11,89,146,41,39,11,248,2,70,248, +22,165,20,198,249,22,7,249,22,80,248,22,164,20,201,196,195,249,22,7,249, +22,80,248,22,164,20,23,203,1,196,195,249,22,7,249,22,80,248,22,164,20, +23,201,1,23,197,1,23,196,1,248,22,144,12,252,22,162,10,248,22,163,4, 23,200,2,248,22,159,4,23,200,2,248,22,160,4,23,200,2,248,22,161,4, 23,200,2,248,22,162,4,23,200,1,28,24,194,2,12,20,13,144,80,144,39, 41,40,80,143,39,59,89,146,40,40,10,249,22,130,5,21,94,2,32,6,19, @@ -1309,29 +1309,29 @@ 27,112,108,97,110,101,116,45,109,111,100,117,108,101,45,110,97,109,101,45,114, 101,115,111,108,118,101,114,12,27,28,23,195,2,28,249,22,169,9,23,197,2, 80,143,42,55,86,94,23,195,1,80,143,40,56,27,248,22,153,5,23,197,2, -27,28,248,22,78,23,195,2,248,22,163,20,23,195,1,23,194,1,28,248,22, -174,15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,131,16,23,197,1, +27,28,248,22,78,23,195,2,248,22,164,20,23,195,1,23,194,1,28,248,22, +175,15,23,194,2,90,144,42,11,89,146,42,39,11,248,22,132,16,23,197,1, 86,95,20,18,144,11,80,143,45,55,199,20,18,144,11,80,143,45,56,192,192, 11,11,28,23,193,2,192,86,94,23,193,1,27,247,22,177,5,28,23,193,2, -192,86,94,23,193,1,247,22,152,16,90,144,42,11,89,146,42,39,11,248,22, -131,16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,167,16,0,11,35, -114,120,34,91,46,93,115,115,36,34,248,22,179,15,23,197,1,249,80,144,44, +192,86,94,23,193,1,247,22,153,16,90,144,42,11,89,146,42,39,11,248,22, +132,16,23,198,2,86,95,23,195,1,23,193,1,28,249,22,168,16,0,11,35, +114,120,34,91,46,93,115,115,36,34,248,22,180,15,23,197,1,249,80,144,44, 61,42,23,199,1,2,26,196,249,80,144,41,57,42,195,10,249,22,12,23,196, -1,80,144,41,54,41,86,96,28,248,22,151,5,23,196,2,12,250,22,181,11, +1,80,144,41,54,41,86,96,28,248,22,151,5,23,196,2,12,250,22,182,11, 2,22,6,21,21,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, -112,97,116,104,63,23,198,2,28,28,23,196,2,248,22,145,14,23,197,2,10, -12,250,22,181,11,2,22,6,20,20,40,111,114,47,99,32,35,102,32,110,97, +112,97,116,104,63,23,198,2,28,28,23,196,2,248,22,146,14,23,197,2,10, +12,250,22,182,11,2,22,6,20,20,40,111,114,47,99,32,35,102,32,110,97, 109,101,115,112,97,99,101,63,41,23,199,2,28,24,193,2,248,24,194,1,23, -196,2,86,94,23,193,1,12,27,250,22,158,2,80,144,44,44,41,248,22,128, -17,247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249, +196,2,86,94,23,193,1,12,27,250,22,158,2,80,144,44,44,41,248,22,129, +17,247,22,145,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1,27,249, 22,80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,46,44,41, -248,22,128,17,247,22,144,14,195,192,86,94,250,22,156,2,248,22,81,23,197, +248,22,129,17,247,22,145,14,195,192,86,94,250,22,156,2,248,22,81,23,197, 2,23,200,2,70,100,101,99,108,97,114,101,100,28,23,198,2,27,28,248,22, 78,248,22,153,5,23,200,2,248,22,152,5,248,22,81,248,22,153,5,23,201, -1,23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,128,17,23,204,1, +1,23,198,1,27,250,22,158,2,80,144,47,44,41,248,22,129,17,23,204,1, 11,28,23,193,2,27,250,22,158,2,248,22,82,23,198,1,23,198,2,11,28, -23,193,2,250,22,156,2,248,22,164,20,23,200,1,23,198,1,23,196,1,12, -12,12,86,94,251,22,138,12,247,22,142,12,67,101,114,114,111,114,6,69,69, +23,193,2,250,22,156,2,248,22,165,20,23,200,1,23,198,1,23,196,1,12, +12,12,86,94,251,22,139,12,247,22,143,12,67,101,114,114,111,114,6,69,69, 100,101,102,97,117,108,116,32,109,111,100,117,108,101,32,110,97,109,101,32,114, 101,115,111,108,118,101,114,32,99,97,108,108,101,100,32,119,105,116,104,32,116, 104,114,101,101,32,97,114,103,117,109,101,110,116,115,32,40,100,101,112,114,101, @@ -1340,20 +1340,20 @@ 112,97,116,104,222,33,84,32,82,88,148,39,43,57,11,2,31,222,33,83,28, 248,22,88,23,197,2,28,248,22,88,195,192,249,22,80,194,248,22,95,197,28, 249,22,171,9,248,22,81,23,199,2,2,35,28,248,22,88,23,196,2,86,95, -23,196,1,23,195,1,250,22,177,11,2,22,6,37,37,116,111,111,32,109,97, +23,196,1,23,195,1,250,22,178,11,2,22,6,37,37,116,111,111,32,109,97, 110,121,32,34,46,46,34,115,32,105,110,32,115,117,98,109,111,100,117,108,101, 32,112,97,116,104,58,32,126,46,115,250,22,91,2,34,28,249,22,171,9,23, -201,2,2,36,23,199,1,28,248,22,174,15,23,200,2,23,199,1,249,22,90, +201,2,2,36,23,199,1,28,248,22,175,15,23,200,2,23,199,1,249,22,90, 28,248,22,64,23,202,2,2,5,2,37,23,201,1,23,200,1,251,2,82,196, -197,248,22,82,199,248,22,164,20,200,251,2,82,196,197,249,22,80,248,22,163, -20,202,200,248,22,164,20,200,251,2,82,196,197,9,197,27,250,22,176,7,27, -28,23,199,2,28,247,22,130,12,248,80,144,47,58,42,23,200,2,11,11,28, +197,248,22,82,199,248,22,165,20,200,251,2,82,196,197,249,22,80,248,22,164, +20,202,200,248,22,165,20,200,251,2,82,196,197,9,197,27,250,22,176,7,27, +28,23,199,2,28,247,22,131,12,248,80,144,47,58,42,23,200,2,11,11,28, 192,192,6,29,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45, -110,97,109,101,45,114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,178, +110,97,109,101,45,114,101,115,111,108,118,101,114,6,2,2,58,32,250,22,179, 16,0,7,35,114,120,34,92,110,34,23,203,1,249,22,137,8,6,23,23,10, 32,32,102,111,114,32,109,111,100,117,108,101,32,112,97,116,104,58,32,126,115, -10,23,202,2,248,22,173,13,28,23,196,2,251,22,181,12,23,198,1,247,22, -27,248,22,90,23,201,1,23,199,1,86,94,23,196,1,250,22,144,13,23,197, +10,23,202,2,248,22,174,13,28,23,196,2,251,22,182,12,23,198,1,247,22, +27,248,22,90,23,201,1,23,199,1,86,94,23,196,1,250,22,145,13,23,197, 1,247,22,27,23,198,1,32,86,88,148,8,36,40,53,11,69,115,115,45,62, 114,107,116,222,33,87,19,248,22,156,7,194,28,249,22,132,4,23,195,4,42, 28,249,22,169,9,7,46,249,22,157,7,197,249,22,184,3,23,199,4,42,28, @@ -1363,9 +1363,9 @@ 2,28,249,22,159,7,194,2,36,2,27,28,249,22,159,7,194,2,35,64,117, 112,192,0,8,35,114,120,34,91,46,93,34,32,90,88,148,8,36,40,50,11, 2,31,222,33,91,28,248,22,88,23,194,2,9,250,22,91,6,4,4,10,32, -32,32,248,22,178,15,248,22,103,23,198,2,248,2,90,248,22,164,20,23,198, +32,32,248,22,179,15,248,22,103,23,198,2,248,2,90,248,22,165,20,23,198, 1,28,249,22,171,9,248,22,82,23,200,2,23,197,1,28,249,22,169,9,248, -22,163,20,23,200,1,23,196,1,251,22,177,11,2,22,6,41,41,99,121,99, +22,164,20,23,200,1,23,196,1,251,22,178,11,2,22,6,41,41,99,121,99, 108,101,32,105,110,32,108,111,97,100,105,110,103,10,32,32,97,116,32,112,97, 116,104,58,32,126,97,10,32,32,112,97,116,104,115,58,126,97,23,200,1,249, 22,1,22,176,7,248,2,90,248,22,95,23,201,1,12,12,247,23,193,1,250, @@ -1374,58 +1374,58 @@ 40,249,22,31,11,80,144,56,41,40,22,191,4,23,201,2,22,129,5,248,28, 23,208,2,20,20,94,88,148,8,36,40,49,11,9,223,15,33,94,23,208,1, 86,94,23,208,1,22,7,28,248,22,64,23,207,2,23,206,1,28,28,248,22, -78,23,207,2,249,22,169,9,248,22,163,20,23,209,2,2,32,11,23,206,1, +78,23,207,2,249,22,169,9,248,22,164,20,23,209,2,2,32,11,23,206,1, 86,94,23,206,1,28,248,22,151,5,23,203,2,27,248,22,153,5,23,204,2, 28,248,22,64,193,249,22,90,2,5,194,192,23,202,2,249,247,22,176,5,23, -201,1,27,248,22,68,248,22,178,15,23,202,1,28,23,204,2,28,250,22,158, -2,248,22,163,20,23,202,1,23,202,1,11,249,22,80,11,205,249,22,80,194, +201,1,27,248,22,68,248,22,179,15,23,202,1,28,23,204,2,28,250,22,158, +2,248,22,164,20,23,202,1,23,202,1,11,249,22,80,11,205,249,22,80,194, 205,192,86,96,28,248,22,161,5,23,196,2,12,28,248,22,155,4,23,198,2, -250,22,179,11,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97, -116,104,23,200,2,250,22,181,11,2,22,2,33,23,198,2,28,28,23,196,2, -248,22,151,5,23,197,2,10,12,250,22,181,11,2,22,6,31,31,40,111,114, +250,22,180,11,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97, +116,104,23,200,2,250,22,182,11,2,22,2,33,23,198,2,28,28,23,196,2, +248,22,151,5,23,197,2,10,12,250,22,182,11,2,22,6,31,31,40,111,114, 47,99,32,35,102,32,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101, 45,112,97,116,104,63,41,23,199,2,28,28,23,197,2,248,22,155,4,23,198, -2,10,12,250,22,181,11,2,22,6,17,17,40,111,114,47,99,32,35,102,32, +2,10,12,250,22,182,11,2,22,6,17,17,40,111,114,47,99,32,35,102,32, 115,121,110,116,97,120,63,41,23,200,2,28,28,248,22,78,23,196,2,249,22, -169,9,248,22,163,20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23, +169,9,248,22,164,20,23,198,2,2,5,11,86,97,23,198,1,23,197,1,23, 196,1,23,193,1,248,22,152,5,248,22,102,23,197,1,28,28,248,22,78,23, -196,2,28,249,22,169,9,248,22,163,20,23,198,2,2,34,28,248,22,78,248, +196,2,28,249,22,169,9,248,22,164,20,23,198,2,2,34,28,248,22,78,248, 22,102,23,197,2,249,22,169,9,248,22,106,23,198,2,2,5,11,11,11,86, 97,23,198,1,23,197,1,23,196,1,23,193,1,248,22,152,5,249,2,81,248, 22,119,23,199,2,248,22,104,23,199,1,28,28,248,22,78,23,196,2,28,249, -22,169,9,248,22,163,20,23,198,2,2,34,28,28,249,22,171,9,248,22,102, +22,169,9,248,22,164,20,23,198,2,2,34,28,28,249,22,171,9,248,22,102, 23,198,2,2,36,10,249,22,171,9,248,22,102,23,198,2,2,35,28,23,196, 2,27,248,22,153,5,23,198,2,28,248,22,64,193,10,28,248,22,78,193,248, -22,64,248,22,163,20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23, +22,64,248,22,164,20,194,11,11,11,11,11,86,96,23,198,1,23,197,1,23, 193,1,27,248,22,153,5,23,198,1,248,22,152,5,249,2,81,28,248,22,78, -23,197,2,248,22,163,20,23,197,2,23,196,2,27,28,249,22,171,9,248,22, -102,23,203,2,2,35,248,22,164,20,200,248,22,104,200,28,248,22,78,23,198, -2,249,22,94,248,22,164,20,199,194,192,28,28,248,22,78,23,196,2,249,22, -169,9,248,22,163,20,23,198,2,2,38,11,86,94,248,80,144,41,8,28,42, +23,197,2,248,22,164,20,23,197,2,23,196,2,27,28,249,22,171,9,248,22, +102,23,203,2,2,35,248,22,165,20,200,248,22,104,200,28,248,22,78,23,198, +2,249,22,94,248,22,165,20,199,194,192,28,28,248,22,78,23,196,2,249,22, +169,9,248,22,164,20,23,198,2,2,38,11,86,94,248,80,144,41,8,28,42, 23,194,2,253,24,199,1,23,201,1,23,202,1,23,203,1,23,204,1,11,80, -143,46,59,28,28,248,22,78,23,196,2,28,249,22,169,9,248,22,163,20,23, +143,46,59,28,28,248,22,78,23,196,2,28,249,22,169,9,248,22,164,20,23, 198,2,2,34,28,248,22,78,248,22,102,23,197,2,249,22,169,9,248,22,106, 23,198,2,2,38,11,11,11,86,94,248,80,144,41,8,28,42,23,194,2,253, 24,199,1,248,22,102,23,202,2,23,202,1,23,203,1,23,204,1,248,22,104, 23,202,1,80,143,46,59,86,94,23,193,1,27,88,148,8,36,40,57,8,240, 0,0,8,0,1,19,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110, 45,101,114,114,225,2,5,3,33,85,27,28,248,22,78,23,198,2,28,249,22, -169,9,2,34,248,22,163,20,23,200,2,27,248,22,102,23,199,2,28,28,249, +169,9,2,34,248,22,164,20,23,200,2,27,248,22,102,23,199,2,28,28,249, 22,171,9,23,195,2,2,36,10,249,22,171,9,23,195,2,2,35,86,94,23, 193,1,28,23,199,2,27,248,22,153,5,23,201,2,28,248,22,78,193,248,22, -163,20,193,192,250,22,177,11,2,22,6,45,45,110,111,32,98,97,115,101,32, +164,20,193,192,250,22,178,11,2,22,6,45,45,110,111,32,98,97,115,101,32, 112,97,116,104,32,102,111,114,32,114,101,108,97,116,105,118,101,32,115,117,98, 109,111,100,117,108,101,32,112,97,116,104,58,32,126,46,115,23,201,2,192,23, 197,2,23,197,2,27,28,248,22,78,23,199,2,28,249,22,169,9,2,34,248, -22,163,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23,202,2,2, +22,164,20,23,201,2,27,28,28,28,249,22,171,9,248,22,102,23,202,2,2, 36,10,249,22,171,9,248,22,102,23,202,2,2,35,23,200,2,11,27,248,22, 153,5,23,202,2,27,28,249,22,171,9,248,22,102,23,204,2,2,35,248,22, -164,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2,249,2,81, -248,22,163,20,23,197,2,249,22,94,248,22,164,20,23,199,1,23,197,1,249, +165,20,23,202,1,248,22,104,23,202,1,28,248,22,78,23,195,2,249,2,81, +248,22,164,20,23,197,2,249,22,94,248,22,165,20,23,199,1,23,197,1,249, 2,81,23,196,1,23,195,1,249,2,81,2,36,28,249,22,171,9,248,22,102, -23,204,2,2,35,248,22,164,20,23,202,1,248,22,104,23,202,1,28,248,22, -78,193,248,22,164,20,193,11,11,11,27,28,248,22,64,23,196,2,27,248,80, -144,46,51,42,249,22,80,23,199,2,248,22,128,17,247,22,144,14,28,23,193, +23,204,2,2,35,248,22,165,20,23,202,1,248,22,104,23,202,1,28,248,22, +78,193,248,22,165,20,193,11,11,11,27,28,248,22,64,23,196,2,27,248,80, +144,46,51,42,249,22,80,23,199,2,248,22,129,17,247,22,145,14,28,23,193, 2,192,86,94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,49,57, 42,248,22,71,23,201,2,11,27,28,248,22,88,23,195,2,2,39,249,22,176, 7,23,197,2,2,40,252,80,144,53,8,23,42,23,205,1,28,248,22,88,23, @@ -1434,58 +1434,58 @@ 153,7,23,196,2,86,94,23,196,1,27,248,80,144,46,8,29,42,23,202,2, 27,248,80,144,47,51,42,249,22,80,23,200,2,23,197,2,28,23,193,2,192, 86,94,23,193,1,90,144,41,11,89,146,41,39,11,249,80,144,50,57,42,23, -201,2,11,28,248,22,88,23,194,2,86,94,23,193,1,249,22,128,16,23,198, -1,248,2,86,23,197,1,250,22,1,22,128,16,23,199,1,249,22,94,249,22, +201,2,11,28,248,22,88,23,194,2,86,94,23,193,1,249,22,129,16,23,198, +1,248,2,86,23,197,1,250,22,1,22,129,16,23,199,1,249,22,94,249,22, 2,32,0,88,148,8,36,40,47,11,9,222,33,88,23,200,1,248,22,90,248, -2,86,23,201,1,28,248,22,174,15,23,196,2,86,94,23,196,1,248,80,144, -45,8,30,42,248,22,138,16,28,248,22,135,16,23,198,2,23,197,2,249,22, -136,16,23,199,2,248,80,144,49,8,29,42,23,205,2,28,249,22,169,9,248, +2,86,23,201,1,28,248,22,175,15,23,196,2,86,94,23,196,1,248,80,144, +45,8,30,42,248,22,139,16,28,248,22,136,16,23,198,2,23,197,2,249,22, +137,16,23,199,2,248,80,144,49,8,29,42,23,205,2,28,249,22,169,9,248, 22,81,23,198,2,2,32,27,248,80,144,46,51,42,249,22,80,23,199,2,248, -22,128,17,247,22,144,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11, +22,129,17,247,22,145,14,28,23,193,2,192,86,94,23,193,1,90,144,41,11, 89,146,41,39,11,249,80,144,49,57,42,248,22,102,23,201,2,11,27,28,248, -22,88,248,22,104,23,201,2,28,248,22,88,23,195,2,249,22,171,16,2,89, +22,88,248,22,104,23,201,2,28,248,22,88,23,195,2,249,22,172,16,2,89, 23,197,2,11,10,27,28,23,194,2,248,2,86,23,197,2,28,248,22,88,23, -196,2,2,39,28,249,22,171,16,2,89,23,198,2,248,2,86,23,197,2,249, +196,2,2,39,28,249,22,172,16,2,89,23,198,2,248,2,86,23,197,2,249, 22,176,7,23,198,2,2,40,27,28,23,195,1,86,94,23,197,1,249,22,94, 28,248,22,88,248,22,104,23,205,2,21,93,6,5,5,109,122,108,105,98,249, 22,1,22,94,249,22,2,80,144,56,8,31,42,248,22,104,23,208,2,23,198, 1,28,248,22,88,23,197,2,86,94,23,196,1,248,22,90,23,198,1,86,94, 23,197,1,23,196,1,252,80,144,55,8,23,42,23,207,1,248,22,81,23,199, -2,248,22,164,20,23,199,1,23,199,1,10,28,249,22,169,9,248,22,163,20, -23,198,2,2,37,248,80,144,45,8,30,42,248,22,138,16,249,22,136,16,248, -22,140,16,248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86, -94,28,28,248,22,174,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23, -201,2,250,22,179,11,69,114,101,113,117,105,114,101,249,22,137,8,6,17,17, +2,248,22,165,20,23,199,1,23,199,1,10,28,249,22,169,9,248,22,164,20, +23,198,2,2,37,248,80,144,45,8,30,42,248,22,139,16,249,22,137,16,248, +22,141,16,248,22,102,23,201,2,248,80,144,49,8,29,42,23,205,2,12,86, +94,28,28,248,22,175,15,23,194,2,10,248,22,184,8,23,194,2,12,28,23, +201,2,250,22,180,11,69,114,101,113,117,105,114,101,249,22,137,8,6,17,17, 98,97,100,32,109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2, -248,22,81,23,199,2,6,0,0,23,204,2,250,22,181,11,2,22,2,33,23, +248,22,81,23,199,2,6,0,0,23,204,2,250,22,182,11,2,22,2,33,23, 198,2,27,28,248,22,184,8,23,195,2,249,22,189,8,23,196,2,39,249,22, -138,16,248,22,139,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22, +139,16,248,22,140,16,23,197,2,11,27,28,248,22,184,8,23,196,2,249,22, 189,8,23,197,2,40,248,80,144,47,8,24,42,23,195,2,90,144,42,11,89, 146,42,39,11,28,248,22,184,8,23,199,2,250,22,7,2,41,249,22,189,8, -23,203,2,41,2,41,248,22,131,16,23,198,2,86,95,23,195,1,23,193,1, +23,203,2,41,2,41,248,22,132,16,23,198,2,86,95,23,195,1,23,193,1, 27,28,248,22,184,8,23,200,2,249,22,189,8,23,201,2,42,249,80,144,52, 61,42,23,197,2,5,0,27,28,248,22,184,8,23,201,2,249,22,189,8,23, 202,2,43,248,22,152,5,23,200,2,27,250,22,158,2,80,144,55,44,41,248, -22,128,17,247,22,144,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1, +22,129,17,247,22,145,14,11,27,28,23,194,2,23,194,1,86,94,23,194,1, 27,249,22,80,247,22,138,2,247,22,138,2,86,94,250,22,156,2,80,144,57, -44,41,248,22,128,17,247,22,144,14,195,192,27,28,23,204,2,248,22,152,5, +44,41,248,22,129,17,247,22,145,14,195,192,27,28,23,204,2,248,22,152,5, 249,22,80,248,22,153,5,23,200,2,23,207,2,23,196,2,86,95,28,23,212, 2,28,250,22,158,2,248,22,81,23,198,2,195,11,86,96,23,211,1,23,204, 1,23,194,1,12,27,251,22,31,11,80,144,59,53,41,9,28,248,22,15,80, -144,60,54,41,80,144,59,54,41,247,22,17,27,248,22,128,17,247,22,144,14, +144,60,54,41,80,144,59,54,41,247,22,17,27,248,22,129,17,247,22,145,14, 86,94,249,22,3,88,148,8,36,40,57,11,9,226,13,12,2,3,33,92,23, 196,2,248,28,248,22,15,80,144,58,54,41,32,0,88,148,39,40,45,11,9, 222,33,93,80,144,57,8,32,42,20,20,98,88,148,39,39,8,25,8,240,12, 64,0,0,9,233,18,21,14,15,12,11,7,6,4,1,2,33,95,23,195,1, 23,194,1,23,197,1,23,207,1,23,214,1,12,28,28,248,22,184,8,23,204, 1,86,94,23,212,1,11,28,23,212,1,28,248,22,153,7,23,206,2,10,28, -248,22,64,23,206,2,10,28,248,22,78,23,206,2,249,22,169,9,248,22,163, +248,22,64,23,206,2,10,28,248,22,78,23,206,2,249,22,169,9,248,22,164, 20,23,208,2,2,32,11,11,249,80,144,56,52,42,28,248,22,153,7,23,208, 2,249,22,80,23,209,1,248,80,144,59,8,29,42,23,215,1,86,94,23,212, -1,249,22,80,23,209,1,248,22,128,17,247,22,144,14,252,22,186,8,23,209, +1,249,22,80,23,209,1,248,22,129,17,247,22,145,14,252,22,186,8,23,209, 1,23,208,1,23,206,1,23,204,1,23,203,1,12,192,86,96,20,18,144,11, 80,143,39,59,248,80,144,40,8,27,40,249,22,31,11,80,144,42,41,40,248, -22,190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,143,15, +22,190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,144,15, 80,144,40,48,42,20,18,144,11,80,143,39,59,248,80,144,40,8,27,40,249, 22,31,11,80,144,42,41,40,20,18,144,11,80,143,39,59,248,80,144,40,8, 27,40,249,22,31,11,80,144,42,41,40,144,39,20,121,145,2,1,39,16,1, @@ -1543,7 +1543,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 9714); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,48,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,1,0,0,8, 0,18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0, 135,0,147,0,231,0,238,0,8,1,0,0,198,1,0,0,3,1,5,105,110, diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 43d7f6a6dc..89cd6c49ca 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -226,10 +226,10 @@ ROSYM static Scheme_Object *quote_symbol; ROSYM static Scheme_Object *letrec_syntaxes_symbol; ROSYM static Scheme_Object *begin_symbol; ROSYM static Scheme_Object *let_values_symbol; -ROSYM static Scheme_Object *internal_define_symbol; ROSYM static Scheme_Object *module_symbol; ROSYM static Scheme_Object *module_begin_symbol; ROSYM static Scheme_Object *expression_symbol; +ROSYM static Scheme_Object *definition_context_symbol; ROSYM Scheme_Object *scheme_stack_dump_key; READ_ONLY static Scheme_Object *zero_rands_ptr; /* &zero_rands_ptr is dummy rands pointer */ @@ -332,15 +332,15 @@ scheme_init_eval (Scheme_Env *env) REGISTER_SO(module_symbol); REGISTER_SO(module_begin_symbol); - REGISTER_SO(internal_define_symbol); REGISTER_SO(expression_symbol); REGISTER_SO(top_level_symbol); + REGISTER_SO(definition_context_symbol); module_symbol = scheme_intern_symbol("module"); module_begin_symbol = scheme_intern_symbol("module-begin"); - internal_define_symbol = scheme_intern_symbol("internal-define"); expression_symbol = scheme_intern_symbol("expression"); top_level_symbol = scheme_intern_symbol("top-level"); + definition_context_symbol = scheme_intern_symbol("definition-context"); REGISTER_SO(app_symbol); REGISTER_SO(datum_symbol); @@ -4955,6 +4955,29 @@ static Scheme_Object *expand_stx(int argc, Scheme_Object **argv) -1, -1, 0, scheme_false, 0, 0); } +int scheme_is_expansion_context_symbol(Scheme_Object *v) +{ + return (SAME_OBJ(v, module_symbol) + || SAME_OBJ(v, module_begin_symbol) + || SAME_OBJ(v, expression_symbol) + || SAME_OBJ(v, top_level_symbol) + || SAME_OBJ(v, definition_context_symbol)); +} + +Scheme_Object *scheme_frame_to_expansion_context_symbol(int flags) +{ + if (flags & SCHEME_TOPLEVEL_FRAME) + return top_level_symbol; + else if (flags & SCHEME_MODULE_FRAME) + return module_symbol; + else if (flags & SCHEME_MODULE_BEGIN_FRAME) + return module_begin_symbol; + else if (flags & SCHEME_INTDEF_FRAME) + return definition_context_symbol; + else + return expression_symbol; +} + Scheme_Object *scheme_generate_lifts_key(void) { char buf[20]; diff --git a/racket/src/racket/src/schminc.h b/racket/src/racket/src/schminc.h index 0e2a470120..3f0adea467 100644 --- a/racket/src/racket/src/schminc.h +++ b/racket/src/racket/src/schminc.h @@ -14,7 +14,7 @@ #define USE_COMPILED_STARTUP 1 -#define EXPECTED_PRIM_COUNT 1134 +#define EXPECTED_PRIM_COUNT 1135 #define EXPECTED_UNSAFE_COUNT 106 #define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_EXTFL_COUNT 45 diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index b572e0205d..e672d75347 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -3378,6 +3378,10 @@ Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o); int scheme_is_set_transformer(Scheme_Object *o); Scheme_Object *scheme_set_transformer_proc(Scheme_Object *o); +int scheme_is_expansion_context_symbol(Scheme_Object *v); +int scheme_expansion_contexts_include(Scheme_Object *o, Scheme_Object *ctx); +Scheme_Object *scheme_frame_to_expansion_context_symbol(int flags); + Scheme_Object *scheme_top_level_require_execute(Scheme_Object *data); Scheme_Object *scheme_case_lambda_execute(Scheme_Object *expr); diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 25734056ff..0fa8a677f9 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.11" +#define MZSCHEME_VERSION "6.2.900.12" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 11 +#define MZSCHEME_VERSION_W 12 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index a99eccc902..8007b205f2 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -58,6 +58,7 @@ READ_ONLY static Scheme_Object *proc_property; READ_ONLY static Scheme_Object *method_property; READ_ONLY static Scheme_Object *rename_transformer_property; READ_ONLY static Scheme_Object *set_transformer_property; +READ_ONLY static Scheme_Object *expansion_contexts_property; READ_ONLY static Scheme_Object *not_free_id_symbol; READ_ONLY static Scheme_Object *scheme_checked_proc_property; READ_ONLY static Scheme_Object *struct_info_proc; @@ -117,6 +118,7 @@ static Scheme_Object *check_output_port_property_value_ok(int argc, Scheme_Objec static Scheme_Object *check_cpointer_property_value_ok(int argc, Scheme_Object *argv[]); static Scheme_Object *check_rename_transformer_property_value_ok(int argc, Scheme_Object *argv[]); static Scheme_Object *check_set_transformer_property_value_ok(int argc, Scheme_Object *argv[]); +static Scheme_Object *check_expansion_contexts_property_value_ok(int argc, Scheme_Object *argv[]); static Scheme_Object *check_checked_proc_property_value_ok(int argc, Scheme_Object *argv[]); static Scheme_Object *unary_acc(int argc, Scheme_Object **argv, Scheme_Object *self); @@ -489,6 +491,18 @@ scheme_init_struct (Scheme_Env *env) scheme_add_global_constant("prop:set!-transformer", set_transformer_property, env); } + { + REGISTER_SO(expansion_contexts_property); + + guard = scheme_make_prim_w_arity(check_expansion_contexts_property_value_ok, + "guard-for-prop:expansion-contexts", + 2, 2); + expansion_contexts_property = scheme_make_struct_type_property_w_guard(scheme_intern_symbol("expansion-contexts"), + guard); + + scheme_add_global_constant("prop:expansion-contexts", expansion_contexts_property, env); + } + { guard = scheme_make_prim_w_arity(check_checked_proc_property_value_ok, @@ -1951,6 +1965,51 @@ static Scheme_Object *check_set_transformer_property_value_ok(int argc, Scheme_O argc, argv); } +/*========================================================================*/ +/* expansion-contexts property */ +/*========================================================================*/ + +static Scheme_Object *check_expansion_contexts_property_value_ok(int argc, Scheme_Object *argv[]) +{ + Scheme_Object *v; + + v = argv[0]; + + while (SCHEME_PAIRP(v)) { + if (!scheme_is_expansion_context_symbol(SCHEME_CAR(v))) + break; + v = SCHEME_CDR(v); + } + + if (SCHEME_NULLP(v)) + return argv[0]; + + wrong_property_contract("guard-for-prop:expression-contexts", + "(lisrof (or/c 'expression 'top-level 'module 'module-begin 'definition-context)", + v); + + return NULL; +} + +int scheme_expansion_contexts_include(Scheme_Object *o, Scheme_Object *ctx) +{ + Scheme_Object *v; + + if (SCHEME_CHAPERONE_STRUCTP(o)) { + v = scheme_chaperone_struct_type_property_ref(expansion_contexts_property, o); + if (v) { + while (!SCHEME_NULLP(v)) { + if (SAME_OBJ(SCHEME_CAR(v), ctx)) + return 1; + v = SCHEME_CDR(v); + } + return 0; + } + } + + return 1; +} + /*========================================================================*/ /* checked-proc property */ /*========================================================================*/ From 53821a4997307e631662759fd3b959d6295938b7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Sep 2015 15:54:41 -0600 Subject: [PATCH 137/381] intern path values in bytecode --- racket/src/racket/src/print.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index 38c338849d..21fb216bd6 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -2603,7 +2603,13 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, /* Needed for srclocs in procedure names */ Scheme_Object *idx; int l; - + + idx = scheme_hash_get(mt->intern_map, obj); + if (!idx) + scheme_hash_set(mt->intern_map, obj, obj); + else + obj = idx; + idx = get_symtab_idx(mt, obj); if (idx) { print_symtab_ref(pp, idx); From a934bdf4445d6dbb15709a8c3b2bd0e91ea019c4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Sep 2015 16:55:56 -0600 Subject: [PATCH 138/381] Adjust the bytecode format to accomodate syntax source locations Make room in the bytecode format for source locations and 'paren-shape property values for syntax objects. Saving source locations increases bytecode size by about 10% on average. Also, convert the internal representation of syntax properties to use immutable hash tables, instead of lists. --- pkgs/base/info.rkt | 2 +- racket/src/racket/src/char.c | 8 +- racket/src/racket/src/cstartup.inc | 10 +- racket/src/racket/src/env.c | 1 + racket/src/racket/src/read.c | 5 +- racket/src/racket/src/schpriv.h | 12 +- racket/src/racket/src/schvers.h | 4 +- racket/src/racket/src/syntax.c | 570 +++++++++++++++-------------- 8 files changed, 317 insertions(+), 295 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 8d35324698..af45814da3 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.12") +(define version "6.2.900.13") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/racket/src/racket/src/char.c b/racket/src/racket/src/char.c index 3870943018..95743af00c 100644 --- a/racket/src/racket/src/char.c +++ b/racket/src/racket/src/char.c @@ -68,9 +68,8 @@ void scheme_init_portable_case(void) init_uchar_table(); } -void scheme_init_char (Scheme_Env *env) +void scheme_init_char_constants(void) { - Scheme_Object *p; int i; REGISTER_SO(scheme_char_constants); @@ -93,6 +92,11 @@ void scheme_init_char (Scheme_Env *env) s = scheme_intern_symbol(general_category_names[i]); general_category_symbols[i] = s; } +} + +void scheme_init_char (Scheme_Env *env) +{ + Scheme_Object *p; p = scheme_make_folding_prim(char_p, "char?", 1, 1, 1); SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index dd227d60fa..8e06f64f38 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,5 +1,5 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,0,1,0,0,8, 0,18,0,22,0,26,0,31,0,38,0,42,0,47,0,59,0,66,0,69,0, 82,0,89,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159, @@ -102,7 +102,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 2092); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,1,0,0,8, 0,16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,178,0, 193,0,211,0,223,0,239,0,253,0,19,1,39,1,73,1,90,1,107,1,130, @@ -1046,7 +1046,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 19760); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,8, 0,23,0,48,0,65,0,83,0,105,0,128,0,149,0,171,0,180,0,189,0, 196,0,205,0,212,0,0,0,247,1,0,0,3,1,5,105,110,115,112,48,76, @@ -1077,7 +1077,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 578); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,1,0,0,8, 0,15,0,26,0,53,0,59,0,73,0,86,0,112,0,129,0,151,0,159,0, 171,0,186,0,202,0,220,0,241,0,253,0,13,1,36,1,60,1,72,1,103, @@ -1543,7 +1543,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 9714); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,50,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,1,0,0,8, 0,18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0, 135,0,147,0,231,0,238,0,8,1,0,0,198,1,0,0,3,1,5,105,110, diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index 2db6ad4505..3f8ee2b2b5 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -707,6 +707,7 @@ static void make_kernel_env(void) MZTIMEIT(numcomp, scheme_init_numcomp(env)); MZTIMEIT(numstr, scheme_init_numstr(env)); MZTIMEIT(bignum, scheme_init_bignum()); + MZTIMEIT(char-const, scheme_init_char_constants()); MZTIMEIT(stx, scheme_init_stx(env)); MZTIMEIT(module, scheme_init_module(env)); MZTIMEIT(port, scheme_init_port(env)); diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 30409ebd00..511128c06c 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -82,7 +82,6 @@ ROSYM static Scheme_Object *syntax_symbol; ROSYM static Scheme_Object *unsyntax_symbol; ROSYM static Scheme_Object *unsyntax_splicing_symbol; ROSYM static Scheme_Object *quasisyntax_symbol; -ROSYM static Scheme_Object *paren_shape_symbol; ROSYM static Scheme_Object *terminating_macro_symbol; ROSYM static Scheme_Object *non_terminating_macro_symbol; ROSYM static Scheme_Object *dispatch_macro_symbol; @@ -416,7 +415,6 @@ void scheme_init_read(Scheme_Env *env) REGISTER_SO(unsyntax_symbol); REGISTER_SO(unsyntax_splicing_symbol); REGISTER_SO(quasisyntax_symbol); - REGISTER_SO(paren_shape_symbol); REGISTER_SO(unresolved_uninterned_symbol); REGISTER_SO(tainted_uninterned_symbol); @@ -433,7 +431,6 @@ void scheme_init_read(Scheme_Env *env) unsyntax_symbol = scheme_intern_symbol("unsyntax"); unsyntax_splicing_symbol = scheme_intern_symbol("unsyntax-splicing"); quasisyntax_symbol = scheme_intern_symbol("quasisyntax"); - paren_shape_symbol = scheme_intern_symbol("paren-shape"); unresolved_uninterned_symbol = scheme_make_symbol("unresolved"); tainted_uninterned_symbol = scheme_make_symbol("tainted"); @@ -2969,7 +2966,7 @@ static Scheme_Object *attach_shape_property(Scheme_Object *list, opener = ((closer == '}') ? scheme_make_ascii_character('{') : scheme_make_ascii_character('[')); - return scheme_stx_property(list, paren_shape_symbol, opener); + return scheme_stx_property(list, scheme_paren_shape_symbol, opener); } return list; } diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index e672d75347..1066d5275e 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -311,6 +311,7 @@ void scheme_init_fun(Scheme_Env *env); void scheme_init_unsafe_fun(Scheme_Env *env); void scheme_init_compile(Scheme_Env *env); void scheme_init_symbol(Scheme_Env *env); +void scheme_init_char_constants(void); void scheme_init_char(Scheme_Env *env); void scheme_init_bool(Scheme_Env *env); void scheme_init_syntax(Scheme_Env *env); @@ -526,6 +527,9 @@ extern Scheme_Object *scheme_recur_symbol, *scheme_display_symbol, *scheme_write extern Scheme_Object *scheme_none_symbol, *scheme_line_symbol, *scheme_block_symbol; +extern Scheme_Object *scheme_paren_shape_symbol; +extern Scheme_Hash_Tree *scheme_source_stx_props; + extern Scheme_Object *scheme_stack_dump_key; extern Scheme_Object *scheme_default_prompt_tag; @@ -1103,7 +1107,7 @@ typedef struct Scheme_Stx { } u; Scheme_Object *shifts; /* or (vector ) */ Scheme_Object *taints; /* taint or taint-arming */ - Scheme_Object *props; + Scheme_Hash_Tree *props; } Scheme_Stx; typedef struct Scheme_Stx_Offset { @@ -1117,11 +1121,11 @@ struct Scheme_Unmarshal_Tables; Scheme_Object *scheme_make_stx(Scheme_Object *val, Scheme_Stx_Srcloc *srcloc, - Scheme_Object *props); + Scheme_Hash_Tree *props); Scheme_Object *scheme_make_stx_w_offset(Scheme_Object *val, intptr_t line, intptr_t col, intptr_t pos, intptr_t span, Scheme_Object *src, - Scheme_Object *props); + Scheme_Hash_Tree *props); Scheme_Object *scheme_datum_to_syntax(Scheme_Object *o, Scheme_Object *stx_src, Scheme_Object *stx_wraps, @@ -1313,7 +1317,7 @@ Scheme_Object *scheme_resolve_placeholders(Scheme_Object *obj); Scheme_Object *scheme_source_to_name(Scheme_Object *code); -#define STX_SRCTAG scheme_false +#define STX_SRCTAG scheme_source_stx_props Scheme_Object *scheme_stx_taint(Scheme_Object *o); Scheme_Object *scheme_stx_taint_arm(Scheme_Object *o, Scheme_Object *insp); diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 0fa8a677f9..0e9f6a01e0 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.12" +#define MZSCHEME_VERSION "6.2.900.13" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 12 +#define MZSCHEME_VERSION_W 13 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 0a986c1d3f..42ad41249c 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -52,6 +52,12 @@ READ_ONLY Scheme_Scope_Table *empty_scope_table; READ_ONLY Scheme_Scope_Table *empty_propagate_table; READ_ONLY Scheme_Scope_Set *empty_scope_set; +ROSYM Scheme_Object *scheme_paren_shape_symbol; + +READ_ONLY Scheme_Hash_Tree *scheme_source_stx_props; +READ_ONLY static Scheme_Hash_Tree *square_stx_props; +READ_ONLY static Scheme_Hash_Tree *curly_stx_props; + READ_ONLY static Scheme_Stx_Srcloc *empty_srcloc; typedef struct Scheme_Scope { @@ -414,6 +420,16 @@ void scheme_init_stx(Scheme_Env *env) REGISTER_SO(root_scope); root_scope = scheme_new_scope(SCHEME_STX_MODULE_SCOPE); + + REGISTER_SO(scheme_paren_shape_symbol); + scheme_paren_shape_symbol = scheme_intern_symbol("paren-shape"); + + REGISTER_SO(scheme_source_stx_props); + REGISTER_SO(square_stx_props); + REGISTER_SO(curly_stx_props); + scheme_source_stx_props = scheme_hash_tree_set(empty_hash_tree, source_symbol, scheme_true); + square_stx_props = scheme_hash_tree_set(empty_hash_tree, scheme_paren_shape_symbol, scheme_make_char('[')); + curly_stx_props = scheme_hash_tree_set(empty_hash_tree, scheme_paren_shape_symbol, scheme_make_char('{')); } void scheme_init_stx_places(int initial_main_os_thread) { @@ -429,7 +445,7 @@ void scheme_init_stx_places(int initial_main_os_thread) { Scheme_Object *scheme_make_stx(Scheme_Object *val, Scheme_Stx_Srcloc *srcloc, - Scheme_Object *props) + Scheme_Hash_Tree *props) { Scheme_Stx *stx; @@ -492,7 +508,7 @@ Scheme_Object *clone_stx(Scheme_Object *to, GC_CAN_IGNORE int *mutate) Scheme_Object *scheme_make_stx_w_offset(Scheme_Object *val, intptr_t line, intptr_t col, intptr_t pos, intptr_t span, Scheme_Object *src, - Scheme_Object *props) + Scheme_Hash_Tree *props) { Scheme_Stx_Srcloc *srcloc; @@ -516,145 +532,64 @@ Scheme_Object *scheme_stx_track(Scheme_Object *naya, { Scheme_Stx *nstx = (Scheme_Stx *)naya; Scheme_Stx *ostx = (Scheme_Stx *)old; - Scheme_Object *ne, *oe, *e1, *e2; + Scheme_Hash_Tree *ne, *oe; + Scheme_Object *e1, *key, *val; + mzlonglong i; - if (nstx->props) { - if (SAME_OBJ(nstx->props, STX_SRCTAG)) { - /* Retain 'source tag. */ - ne = ICONS(ICONS(source_symbol, scheme_true), scheme_null); - } else - ne = nstx->props; - } else - ne = scheme_null; + if (nstx->props) + ne = nstx->props; + else + ne = empty_hash_tree; if (ostx->props) { if (SAME_OBJ(ostx->props, STX_SRCTAG)) { - /* Drop 'source, add 'origin. */ - oe = NULL; + /* Drop 'source; will add 'origin. */ + oe = empty_hash_tree; } else { - Scheme_Object *p, *a; - int mod = 0, add = 1; - oe = ostx->props; - /* Drop 'source and 'share, add 'origin if not there */ - for (p = oe; SCHEME_PAIRP(p); p = SCHEME_CDR(p)) { - a = SCHEME_CAR(SCHEME_CAR(p)); - if (SAME_OBJ(a, source_symbol) || SAME_OBJ(a, share_symbol)) - mod = 1; - else if (SAME_OBJ(a, origin_symbol)) - mod = 1; - } - - if (mod) { - Scheme_Object *first = scheme_null, *last = NULL; - - for (; SCHEME_PAIRP(oe); oe = SCHEME_CDR(oe)) { - a = SCHEME_CAR(SCHEME_CAR(oe)); - if (!SAME_OBJ(a, source_symbol) && !SAME_OBJ(a, share_symbol)) { - if (!origin || !SAME_OBJ(a, origin_symbol)) { - p = ICONS(SCHEME_CAR(oe), scheme_null); - } else { - p = ICONS(ICONS(a, ICONS(origin, - SCHEME_CDR(SCHEME_CAR(oe)))), - scheme_null); - add = 0; - } - - if (last) - SCHEME_CDR(last) = p; - else - first = p; - last = p; - } - } - - oe = first; - } - if (add && origin) { - oe = ICONS(ICONS(origin_symbol, - ICONS(origin, scheme_null)), - oe); - } + /* Drop 'source and 'share; will add 'origin */ + oe = scheme_hash_tree_set(oe, source_symbol, NULL); + oe = scheme_hash_tree_set(oe, share_symbol, NULL); } } else { - /* Add 'origin. */ - oe = NULL; + /* Will add 'origin */ + oe = empty_hash_tree; } - if (!oe) { - if (origin) - oe = ICONS(ICONS(origin_symbol, - ICONS(origin, scheme_null)), - scheme_null); - else - oe = scheme_null; - } + e1 = scheme_hash_tree_get(oe, origin_symbol); + if (e1 && origin) + oe = scheme_hash_tree_set(oe, origin_symbol, ICONS(origin, e1)); + else if (origin) + oe = scheme_hash_tree_set(oe, origin_symbol, ICONS(origin, scheme_null)); + + /* Merge ne and oe */ - /* Merge ne and oe (ne takes precedence). */ - - /* First, check for overlap: */ - for (e1 = ne; SCHEME_PAIRP(e1); e1 = SCHEME_CDR(e1)) { - Scheme_Object *a; - a = SCHEME_CAR(SCHEME_CAR(e1)); - for (e2 = oe; SCHEME_PAIRP(e2); e2 = SCHEME_CDR(e2)) { - if (SAME_OBJ(SCHEME_CAR(SCHEME_CAR(e2)), a)) { - break; - } - } - if (!SCHEME_NULLP(e1)) - break; - } - - if (SCHEME_NULLP(e1)) { - /* Can just append props info (probably the common case). */ - if (!SCHEME_NULLP(oe)) - ne = scheme_append(ne, oe); - } else { - /* Have to perform an actual merge: */ - Scheme_Object *first = scheme_null, *last = NULL, *p; - - for (e1 = ne; SCHEME_PAIRP(e1); e1 = SCHEME_CDR(e1)) { - Scheme_Object *a, *v; - a = SCHEME_CAR(SCHEME_CAR(e1)); - v = SCHEME_CDR(SCHEME_CAR(e1)); - for (e2 = oe; SCHEME_PAIRP(e2); e2 = SCHEME_CDR(e2)) { - if (SAME_OBJ(SCHEME_CAR(SCHEME_CAR(e2)), a)) { - v = ICONS(v, SCHEME_CDR(SCHEME_CAR(e2))); - break; - } - } - - p = ICONS(ICONS(a, v), scheme_null); - if (last) - SCHEME_CDR(last) = p; + if (SAME_OBJ(ne, empty_hash_tree)) + ne = oe; + else if (ne->count < oe->count) { + i = scheme_hash_tree_next(ne, -1); + while (i != -1) { + scheme_hash_tree_index(ne, i, &key, &val); + e1 = scheme_hash_tree_get(oe, key); + if (e1) + oe = scheme_hash_tree_set(oe, key, ICONS(val, e1)); else - first = p; - last = p; + oe = scheme_hash_tree_set(oe, key, val); + i = scheme_hash_tree_next(ne, i); } - - for (e1 = oe; SCHEME_PAIRP(e1); e1 = SCHEME_CDR(e1)) { - Scheme_Object *a, *v; - a = SCHEME_CAR(SCHEME_CAR(e1)); - v = SCHEME_CDR(SCHEME_CAR(e1)); - for (e2 = ne; SCHEME_PAIRP(e2); e2 = SCHEME_CDR(e2)) { - if (SAME_OBJ(SCHEME_CAR(SCHEME_CAR(e2)), a)) { - v = NULL; - break; - } - } - - if (v) { - p = ICONS(ICONS(a, v), scheme_null); - if (last) - SCHEME_CDR(last) = p; - else - first = p; - last = p; - } + ne = oe; + } else { + i = scheme_hash_tree_next(oe, -1); + while (i != -1) { + scheme_hash_tree_index(oe, i, &key, &val); + e1 = scheme_hash_tree_get(ne, key); + if (e1) + ne = scheme_hash_tree_set(ne, key, ICONS(e1, val)); + else + ne = scheme_hash_tree_set(ne, key, val); + i = scheme_hash_tree_next(oe, i); } - - ne = first; } /* Clone nstx, keeping wraps, changing props to ne */ @@ -6138,64 +6073,156 @@ Scheme_Object *scheme_scope_marshal_content(Scheme_Object *m, Scheme_Marshal_Tab = | ... - = (cons (cons (cons ... )) ) - | (cons (cons ... null) ) - | (cons (cons #t ) ) + = (MK (cons (cons ... )) ) + | (MK (cons ... null) ) + | (MK (cons #t ) ) ; where has no boxes or vectors, and - ; is shared in all elements - = (cons (box ) ) - = (cons (vector ...) ) - = (cons ) + ; , , and are shared in all elements + = (MK (box ) ) + = (MK (vector ...) ) + = (MK ) ; where is not a pair, vector, or box + + where + + (MK #f 0) = (cons ) + (MK 0) = (vector ) + (MK #f ) = (vector ) + (MK ) = (vector ) + */ -static Scheme_Object *extract_for_common_wrap(Scheme_Object *a, int get_scope, int pair_ok) +#define COMMON_EXTRACT_DATUM 0 +#define COMMON_EXTRACT_WRAPS 1 +#define COMMON_EXTRACT_SRCLOC 2 +#define COMMON_EXTRACT_TAINT 3 + +static Scheme_Object *extract_for_common_wrap(Scheme_Object *a, int get_part, int pair_ok) { /* We only share wraps for things constucted with pairs and atomic (w.r.t. syntax) values. */ - Scheme_Object *v; + Scheme_Object *v, *wraps, *srcloc, *taint; if (SCHEME_PAIRP(a)) { v = SCHEME_CAR(a); + wraps = SCHEME_CDR(a); + srcloc = scheme_false; + taint = scheme_make_integer(0); + } else if (SCHEME_VECTORP(a)) { + v = SCHEME_VEC_ELS(a)[0]; + wraps = SCHEME_VEC_ELS(a)[1]; + srcloc = SCHEME_VEC_ELS(a)[2]; + if (SCHEME_INTP(srcloc)) { /* an integer is a taint or arm value */ + taint = srcloc; + srcloc = scheme_false; + } else if (SCHEME_VEC_SIZE(a) > 3) + taint = SCHEME_VEC_ELS(a)[3]; + else + taint = scheme_make_integer(0); + } else + return NULL; - if (SCHEME_PAIRP(v)) { - if (pair_ok && SAME_OBJ(SCHEME_CAR(v), scheme_true)) { - /* A pair with shared wraps for its elements */ - if (get_scope) - return SCHEME_CDR(a); - else - return SCHEME_CDR(v); - } - } else if (!SCHEME_NULLP(v) && !SCHEME_BOXP(v) && !SCHEME_VECTORP(v) && !SCHEME_HASHTRP(v) && !prefab_p(v)) { - /* It's atomic. */ - if (get_scope) - return SCHEME_CDR(a); + if (SCHEME_PAIRP(v)) { + if (pair_ok && SAME_OBJ(SCHEME_CAR(v), scheme_true)) { + /* A pair with shared wraps for its elements */ + if (get_part == COMMON_EXTRACT_WRAPS) + return wraps; + else if (get_part == COMMON_EXTRACT_SRCLOC) + return srcloc; + else if (get_part == COMMON_EXTRACT_TAINT) + return taint; else - return v; + return SCHEME_CDR(v); } + } else if (!SCHEME_NULLP(v) && !SCHEME_BOXP(v) && !SCHEME_VECTORP(v) && !SCHEME_HASHTRP(v) && !prefab_p(v)) { + /* It's atomic. */ + if (get_part == COMMON_EXTRACT_WRAPS) + return wraps; + else if (get_part == COMMON_EXTRACT_SRCLOC) + return srcloc; + else if (get_part == COMMON_EXTRACT_TAINT) + return taint; + else + return v; } return NULL; } -static void lift_common_wraps(Scheme_Object *l, Scheme_Object *common_wraps, int cnt, int tail) +static void lift_common_wraps(Scheme_Object *l, int cnt, int tail) { Scheme_Object *a; while (cnt--) { a = SCHEME_CAR(l); - a = extract_for_common_wrap(a, 0, 1); + a = extract_for_common_wrap(a, COMMON_EXTRACT_DATUM, 1); SCHEME_CAR(l) = a; if (cnt) l = SCHEME_CDR(l); } if (tail) { a = SCHEME_CDR(l); - a = extract_for_common_wrap(a, 0, 0); + a = extract_for_common_wrap(a, COMMON_EXTRACT_DATUM, 0); SCHEME_CDR(l) = a; } } +static Scheme_Object *convert_srcloc(Scheme_Stx_Srcloc *srcloc, Scheme_Hash_Tree *props, Scheme_Marshal_Tables *mt) +{ + Scheme_Object *vec, *paren; + + if (!srcloc) + return scheme_false; + + if (props) { + paren = scheme_hash_tree_get(props, scheme_paren_shape_symbol); + if (paren && !SCHEME_CHARP(paren)) + paren = NULL; + } else + paren = NULL; + + vec = scheme_make_vector((paren ? 6 : 5), NULL); + SCHEME_VEC_ELS(vec)[0] = srcloc->src; + SCHEME_VEC_ELS(vec)[1] = scheme_make_integer(srcloc->line); + SCHEME_VEC_ELS(vec)[2] = scheme_make_integer(srcloc->col); + SCHEME_VEC_ELS(vec)[3] = scheme_make_integer(srcloc->pos); + SCHEME_VEC_ELS(vec)[4] = scheme_make_integer(srcloc->span); + if (paren) + SCHEME_VEC_ELS(vec)[5] = paren; + + return intern_one(vec, mt->intern_map); +} + +static void unconvert_srcloc(Scheme_Object *srcloc_vec, Scheme_Stx *dest) +{ + Scheme_Stx_Srcloc *srcloc; + + if (!SCHEME_VECTORP(srcloc_vec) + || ((SCHEME_VEC_SIZE(srcloc_vec) != 5) + && (SCHEME_VEC_SIZE(srcloc_vec) != 6))) + return; + + srcloc = MALLOC_ONE_RT(Scheme_Stx_Srcloc); +#ifdef MZTAG_REQUIRED + srcloc->type = scheme_rt_srcloc; +#endif + srcloc->src = SCHEME_VEC_ELS(srcloc_vec)[0]; + srcloc->line = SCHEME_INT_VAL(SCHEME_VEC_ELS(srcloc_vec)[1]); + srcloc->col = SCHEME_INT_VAL(SCHEME_VEC_ELS(srcloc_vec)[2]); + srcloc->pos = SCHEME_INT_VAL(SCHEME_VEC_ELS(srcloc_vec)[3]); + srcloc->span = SCHEME_INT_VAL(SCHEME_VEC_ELS(srcloc_vec)[4]); + + dest->srcloc = srcloc; + + if ((SCHEME_VEC_SIZE(srcloc_vec) > 5) + && SCHEME_CHARP((SCHEME_VEC_ELS(srcloc_vec)[5]))) { + if (SCHEME_CHAR_VAL(SCHEME_VEC_ELS(srcloc_vec)[5]) == '[') + dest->props = square_stx_props; + else if (SCHEME_CHAR_VAL(SCHEME_VEC_ELS(srcloc_vec)[5]) == '{') + dest->props = curly_stx_props; + } +} + #ifdef DO_STACK_CHECK static Scheme_Object *syntax_to_datum_inner(Scheme_Object *o, int with_scopes, @@ -6215,7 +6242,7 @@ static Scheme_Object *syntax_to_datum_k(void) #endif static Scheme_Object *syntax_to_datum_inner(Scheme_Object *o, - int with_scopes, /* abs > 1 => marshal; negative => implicitly tainted */ + int with_scopes, /* non-zero => marshal; negative => implicitly tainted */ Scheme_Marshal_Tables *mt) { Scheme_Stx *stx = (Scheme_Stx *)o; @@ -6252,12 +6279,12 @@ static Scheme_Object *syntax_to_datum_inner(Scheme_Object *o, v = stx->val; if (SCHEME_PAIRP(v)) { - Scheme_Object *first = NULL, *last = NULL, *p, *common_wraps = NULL; + Scheme_Object *first = NULL, *last = NULL, *p; + Scheme_Object *common_wraps = NULL, *common_srcloc = NULL, *common_taint = NULL; + Scheme_Object *a, *sa, *ta; int cnt = 0; while (SCHEME_PAIRP(v)) { - Scheme_Object *a; - cnt++; a = syntax_to_datum_inner(SCHEME_CAR(v), with_scopes, mt); @@ -6272,13 +6299,20 @@ static Scheme_Object *syntax_to_datum_inner(Scheme_Object *o, v = SCHEME_CDR(v); if (with_scopes) { - a = extract_for_common_wrap(a, 1, 1); + sa = extract_for_common_wrap(a, COMMON_EXTRACT_SRCLOC, 1); + ta = extract_for_common_wrap(a, COMMON_EXTRACT_TAINT, 1); + a = extract_for_common_wrap(a, COMMON_EXTRACT_WRAPS, 1); if (!common_wraps) { - if (a) + if (a) { common_wraps = a; - else + common_srcloc = sa; + common_taint = ta; + } else common_wraps = scheme_false; - } else if (!a || !SAME_OBJ(common_wraps, a)) + } else if (!a + || !SAME_OBJ(common_wraps, a) + || !SAME_OBJ(common_srcloc, sa) + || !SAME_OBJ(common_taint, ta)) common_wraps = scheme_false; } } @@ -6287,18 +6321,26 @@ static Scheme_Object *syntax_to_datum_inner(Scheme_Object *o, SCHEME_CDR(last) = v; if (with_scopes) { - v = extract_for_common_wrap(v, 1, 0); - if (v && SAME_OBJ(common_wraps, v)) { + sa = extract_for_common_wrap(v, COMMON_EXTRACT_SRCLOC, 0); + ta = extract_for_common_wrap(v, COMMON_EXTRACT_TAINT, 0); + v = extract_for_common_wrap(v, COMMON_EXTRACT_WRAPS, 0); + if (v + && SAME_OBJ(common_wraps, v) + && SAME_OBJ(common_srcloc, sa) + && SAME_OBJ(common_taint, ta)) { converted_wraps = wraps_to_datum(stx, mt); - if (SAME_OBJ(common_wraps, converted_wraps)) - lift_common_wraps(first, common_wraps, cnt, 1); + sa = convert_srcloc(stx->srcloc, stx->props, mt); + if (SAME_OBJ(common_wraps, converted_wraps) + && SAME_OBJ(common_srcloc, sa) + && SAME_OBJ(common_taint, scheme_make_integer(add_taint))) + lift_common_wraps(first, cnt, 1); else common_wraps = scheme_false; } else common_wraps = scheme_false; } - if (((with_scopes > 1) || (with_scopes < -1)) && SCHEME_FALSEP(common_wraps)) { + if (with_scopes && SCHEME_FALSEP(common_wraps)) { /* v is likely a pair, and v's car might be a pair, which means that the datum->syntax part won't be able to detect that v is a "non-pair" @@ -6308,8 +6350,11 @@ static Scheme_Object *syntax_to_datum_inner(Scheme_Object *o, } } else if (with_scopes && SCHEME_TRUEP(common_wraps)) { converted_wraps = wraps_to_datum(stx, mt); - if (SAME_OBJ(common_wraps, converted_wraps)) - lift_common_wraps(first, common_wraps, cnt, 0); + sa = convert_srcloc(stx->srcloc, stx->props, mt); + if (SAME_OBJ(common_wraps, converted_wraps) + && SAME_OBJ(common_srcloc, sa) + && SAME_OBJ(common_taint, scheme_make_integer(add_taint))) + lift_common_wraps(first, cnt, 0); else common_wraps = scheme_false; } @@ -6367,16 +6412,22 @@ static Scheme_Object *syntax_to_datum_inner(Scheme_Object *o, } else result = v; - if ((with_scopes > 1) || (with_scopes < -1)) { + if (with_scopes) { if (!converted_wraps) converted_wraps = wraps_to_datum(stx, mt); - result = CONS(result, converted_wraps); - if (add_taint == 1) - result = scheme_make_vector(1, result); /* vector of size 1 => tainted */ - else if (add_taint == 2) { - result = scheme_make_vector(2, result); /* vector of size 2 => armed */ - SCHEME_VEC_ELS(result)[1] = scheme_false; - } + v = convert_srcloc(stx->srcloc, stx->props, mt); + if (SCHEME_TRUEP(v)) { + result = scheme_make_vector((add_taint ? 4 : 3), result); + SCHEME_VEC_ELS(result)[1] = converted_wraps; + SCHEME_VEC_ELS(result)[2] = v; + if (add_taint) + SCHEME_VEC_ELS(result)[3] = scheme_make_integer(add_taint); /* 1 => tainted, 2 => armed */ + } else if (add_taint) { + result = scheme_make_vector(3, result); + SCHEME_VEC_ELS(result)[1] = converted_wraps; + SCHEME_VEC_ELS(result)[2] = scheme_make_integer(add_taint); /* 1 => tainted, 2 => armed */ + } else + result = CONS(result, converted_wraps); } return result; @@ -6544,7 +6595,6 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, return multi_scopes; } - static Scheme_Object *datum_to_wraps(Scheme_Object *w, Scheme_Unmarshal_Tables *ut) { @@ -6819,12 +6869,12 @@ static Scheme_Object *datum_to_syntax_k(void) static Scheme_Object *datum_to_syntax_inner(Scheme_Object *o, Scheme_Unmarshal_Tables *ut, Scheme_Stx *stx_src, - Scheme_Stx *stx_wraps, /* or rename table, or boxed precomputed wrap */ + Scheme_Stx *stx_wraps, /* or rename table, or vectored wrap+srcloc+taint */ Scheme_Hash_Table *ht, int tainted) { - Scheme_Object *result, *wraps, *hashed; - int do_not_unpack_wraps = 0, armed = 0; + Scheme_Object *result, *wraps, *hashed, *srcloc_vec; + int do_not_unpack_wraps = 0, taintval = 0; if (SCHEME_STXP(o)) return o; @@ -6861,30 +6911,42 @@ static Scheme_Object *datum_to_syntax_inner(Scheme_Object *o, } else hashed = NULL; - if (ut && !SCHEME_BOXP(stx_wraps)) { + srcloc_vec = scheme_false; + + if (ut && !SCHEME_VECTORP(stx_wraps)) { if (SCHEME_VECTORP(o)) { - if (SCHEME_VEC_SIZE(o) == 1) { - /* tainted --- forced on all enclosed syntax objects, too */ - o = SCHEME_VEC_ELS(o)[0]; - tainted = 1; - } else if (SCHEME_VEC_SIZE(o) == 2) { - /* armed */ - o = SCHEME_VEC_ELS(o)[0]; - armed = 1; + if (SCHEME_VEC_SIZE(o) == 4) { + srcloc_vec = SCHEME_VEC_ELS(o)[2]; + taintval = SCHEME_INT_VAL(SCHEME_VEC_ELS(o)[3]); + } else if (SCHEME_VEC_SIZE(o) == 3) { + if (SCHEME_INTP(SCHEME_VEC_ELS(o)[2])) + taintval = SCHEME_INT_VAL(SCHEME_VEC_ELS(o)[2]); + else { + srcloc_vec = SCHEME_VEC_ELS(o)[2]; + taintval = 0; + } } else - return_NULL; + return_NULL; + wraps = SCHEME_VEC_ELS(o)[1]; + o = SCHEME_VEC_ELS(o)[0]; + } else { + if (!SCHEME_PAIRP(o)) + return_NULL; + wraps = SCHEME_CDR(o); + o = SCHEME_CAR(o); } - if (!SCHEME_PAIRP(o)) - return_NULL; - wraps = SCHEME_CDR(o); - o = SCHEME_CAR(o); - } else if (SCHEME_BOXP(stx_wraps)) { + } else if (SCHEME_VECTORP(stx_wraps)) { /* Shared wraps, to be used directly everywhere: */ - wraps = SCHEME_BOX_VAL(stx_wraps); + wraps = SCHEME_VEC_ELS(stx_wraps)[0]; + srcloc_vec = SCHEME_VEC_ELS(stx_wraps)[1]; + taintval = SCHEME_INT_VAL(SCHEME_VEC_ELS(stx_wraps)[2]); do_not_unpack_wraps = 1; } else wraps = NULL; + if (taintval == 1) + tainted = 1; + if (SCHEME_PAIRP(o)) { Scheme_Object *first = NULL, *last = NULL, *p; @@ -6902,16 +6964,18 @@ static Scheme_Object *datum_to_syntax_inner(Scheme_Object *o, int cnt = -1; Scheme_Stx *sub_stx_wraps = stx_wraps; - if (wraps && !SCHEME_BOXP(stx_wraps) && SAME_OBJ(SCHEME_CAR(o), scheme_true)) { + if (wraps && !SCHEME_VECTORP(stx_wraps) && SAME_OBJ(SCHEME_CAR(o), scheme_true)) { /* Resolve wraps now, and then share it with all nested objects (as indicated by a box for stx_wraps). */ wraps = datum_to_wraps(wraps, ut); if (!wraps) return_NULL; do_not_unpack_wraps = 1; - sub_stx_wraps = (Scheme_Stx *)scheme_box(wraps); + sub_stx_wraps = (Scheme_Stx *)scheme_make_vector(3, wraps); + SCHEME_VEC_ELS((Scheme_Object *)sub_stx_wraps)[1] = srcloc_vec; + SCHEME_VEC_ELS((Scheme_Object *)sub_stx_wraps)[2] = scheme_make_integer(taintval); o = SCHEME_CDR(o); - } else if (wraps && !SCHEME_BOXP(stx_wraps) && SCHEME_INTP(SCHEME_CAR(o))) { + } else if (wraps && !SCHEME_VECTORP(stx_wraps) && SCHEME_INTP(SCHEME_CAR(o))) { /* First element is the number of items before a non-null terminal: */ cnt = SCHEME_INT_VAL(SCHEME_CAR(o)); @@ -7037,8 +7101,7 @@ static Scheme_Object *datum_to_syntax_inner(Scheme_Object *o, if (tainted) { int mutate = MUTATE_STX_OBJ; (void)add_taint_to_stx(result, &mutate); - } - else if (armed) { + } else if (taintval == 2) { /* Arm with #f as the inspector; #f is replaced by a specific inspector when the encloding code is instanted */ Scheme_Object *l; @@ -7047,6 +7110,9 @@ static Scheme_Object *datum_to_syntax_inner(Scheme_Object *o, ((Scheme_Stx *)result)->taints = l; } + if (SCHEME_TRUEP(srcloc_vec)) + unconvert_srcloc(srcloc_vec, (Scheme_Stx *)result); + if (wraps) { if (!do_not_unpack_wraps) { wraps = datum_to_wraps(wraps, ut); @@ -7207,7 +7273,8 @@ static int pos_exact_or_false_p(Scheme_Object *o) static Scheme_Object *datum_to_syntax(int argc, Scheme_Object **argv) { - Scheme_Object *src = scheme_false, *properties = NULL; + Scheme_Object *src = scheme_false; + Scheme_Hash_Tree *properties = NULL; if (!SCHEME_FALSEP(argv[0]) && !SCHEME_STXP(argv[0])) scheme_wrong_contract("datum->syntax", "(or/c syntax? #f)", 0, argc, argv); @@ -7438,20 +7505,8 @@ static Scheme_Object *syntax_original_p(int argc, Scheme_Object **argv) stx = (Scheme_Stx *)argv[0]; if (stx->props) { - if (SAME_OBJ(stx->props, STX_SRCTAG)) { - /* Check for scopes... */ - } else { - Scheme_Object *e; - - for (e = stx->props; SCHEME_PAIRP(e); e = SCHEME_CDR(e)) { - if (SAME_OBJ(source_symbol, SCHEME_CAR(SCHEME_CAR(e)))) { - break; - } - } - - if (SCHEME_NULLP(e)) - return scheme_false; - } + if (!scheme_hash_tree_get(stx->props, source_symbol)) + return scheme_false; } else return scheme_false; @@ -7474,67 +7529,26 @@ Scheme_Object *scheme_stx_property(Scheme_Object *_stx, Scheme_Object *val) { Scheme_Stx *stx; - Scheme_Object *l; + Scheme_Hash_Tree *props; stx = (Scheme_Stx *)_stx; - if (stx->props) { - if (SAME_OBJ(stx->props, STX_SRCTAG)) { - if (val) - l = CONS(CONS(source_symbol, scheme_true), - scheme_null); - else - l = NULL; - } else { - Scheme_Object *e; - - for (e = stx->props; SCHEME_PAIRP(e); e = SCHEME_CDR(e)) { - if (SAME_OBJ(key, SCHEME_CAR(SCHEME_CAR(e)))) { - if (val) - break; - else - return SCHEME_CDR(SCHEME_CAR(e)); - } - } - - if (SCHEME_NULLP(e)) - l = stx->props; - else { - /* Remove existing binding: */ - Scheme_Object *first = scheme_null, *last = NULL, *p; - - for (e = stx->props; SCHEME_PAIRP(e); e = SCHEME_CDR(e)) { - if (SAME_OBJ(key, SCHEME_CAR(SCHEME_CAR(e)))) { - p = SCHEME_CDR(e); - e = NULL; - } else { - p = CONS(SCHEME_CAR(e), scheme_null); - } - - if (last) - SCHEME_CDR(last) = p; - else - first = p; - last = p; - - if (!e) - break; - } - - l = first; - } - } - } else - l = scheme_null; + props = stx->props; + if (!props) + props = empty_hash_tree; if (val) { - l = CONS(CONS(key, val), l); + props = scheme_hash_tree_set(props, key, val); stx = (Scheme_Stx *)clone_stx((Scheme_Object *)stx, NULL); - stx->props = l; - + stx->props = props; return (Scheme_Object *)stx; - } else - return scheme_false; + } else { + val = scheme_hash_tree_get(props, key); + if (!val) + return scheme_false; + else + return val; + } } static Scheme_Object *syntax_property(int argc, Scheme_Object **argv) @@ -7557,16 +7571,18 @@ static Scheme_Object *syntax_property_keys(int argc, Scheme_Object **argv) stx = (Scheme_Stx *)argv[0]; if (stx->props) { - if (!SAME_OBJ(stx->props, STX_SRCTAG)) { - Scheme_Object *e, *k, *l = scheme_null; - - for (e = stx->props; SCHEME_PAIRP(e); e = SCHEME_CDR(e)) { - k = SCHEME_CAR(SCHEME_CAR(e)); - if (SCHEME_SYMBOLP(k) && !SCHEME_SYM_WEIRDP(k)) - l = scheme_make_pair(k, l); - } - return l; + mzlonglong i; + Scheme_Object *key, *l = scheme_null; + + i = scheme_hash_tree_next(stx->props, -1); + while (i != -1) { + scheme_hash_tree_index(stx->props, i, &key, NULL); + if (SCHEME_SYMBOLP(key) && !SCHEME_SYM_WEIRDP(key)) + l = scheme_make_pair(key, l); + i = scheme_hash_tree_next(stx->props, i); } + + return l; } return scheme_null; From fb8e08a2acb6dc80fa7c0903cb26fa6f100d3af4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Sep 2015 09:13:43 -0600 Subject: [PATCH 139/381] adjust path encoding in bytecode and syntax-object sources When a path is made relative for marshaling to bytecode, record a list of byte strings in stead of a platform-specific relative path. For syntax-object source locations, convert any non-relative path to a string that shows just the last couple of path elements preceded by ".../". This conversion avoids embedding absolute paths in bytecode, but at the cost of some information. A more complete and consistent solution would invove using a module-path index instead of a path, but that would be a big change at several layers. --- .../tests/racket/optimize.rktl | 11 ++- racket/collects/racket/private/name.rkt | 5 +- racket/src/racket/src/compile.c | 33 ++++++-- racket/src/racket/src/file.c | 83 ++++++++++++++++--- racket/src/racket/src/marshal.c | 8 +- racket/src/racket/src/mzmark_print.inc | 2 + racket/src/racket/src/mzmarksrc.c | 1 + racket/src/racket/src/portfun.c | 2 +- racket/src/racket/src/print.c | 21 +++-- racket/src/racket/src/read.c | 28 ++++--- racket/src/racket/src/schpriv.h | 8 +- racket/src/racket/src/string.c | 8 ++ racket/src/racket/src/syntax.c | 60 ++++++++++++-- 13 files changed, 220 insertions(+), 50 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 90096b6dee..7c930886e5 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -885,7 +885,6 @@ [t2 (get-output-bytes s2)]) (or (bytes=? t1 t2) (begin - #; (printf "~s\n~s\n" (zo-parse (open-input-bytes t1)) (zo-parse (open-input-bytes t2))) @@ -896,7 +895,11 @@ (case-lambda [(expr1 expr2) (test-comp expr1 expr2 #t)] [(expr1 expr2 same?) - (test same? `(compile ,same? ,expr2) (comp=? (compile expr1) (compile expr2)))])) + (define (->stx s) + ;; Give `s` a minimal location, so that other macro locations + ;; don't bleed through: + (datum->syntax #f s (vector 'here #f #f #f #f))) + (test same? `(compile ,same? ,expr2) (comp=? (compile (->stx expr1)) (compile (->stx expr2))))])) (let ([x (compile '(lambda (x) x))]) (test #t 'fixpt (eq? x (compile x)))) @@ -1669,7 +1672,9 @@ '(letrec ([x (cons 1 1)][y x]) (cons x x))) (test-comp '(let ([f (lambda (x) x)]) f) - (syntax-property (datum->syntax #f '(lambda (x) x)) 'inferred-name 'f)) + (syntax-property (datum->syntax #f '(lambda (x) x) (vector 'here #f #f #f #f)) + 'inferred-name + 'f)) (test-comp '(letrec ([f (lambda (x) x)]) (f 10) diff --git a/racket/collects/racket/private/name.rkt b/racket/collects/racket/private/name.rkt index cbce41ad7e..bb0277ba60 100644 --- a/racket/collects/racket/private/name.rkt +++ b/racket/collects/racket/private/name.rkt @@ -19,7 +19,10 @@ (let ([s (let ([s (format "~a" (cond - [(path? s) (path->string s)] + [(path? s) + ;; Make the result consistent across platforms by + ;; converting backslashes to forward slashes: + (regexp-replace* #rx"\\\\" (path->string s) "/")] [else s]))]) (if ((string-length s) . > . 20) (string-append "..." (substring s (- (string-length s) 20))) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 7f0103a568..3cf212b65d 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -457,22 +457,43 @@ static void lambda_check_args(Scheme_Object *args, Scheme_Object *form, Scheme_C } Scheme_Object *scheme_source_to_name(Scheme_Object *code) - /* Makes up a procedure name when there's not a good one in the source: */ +/* Makes up a procedure name when there's not a good one in the source */ { Scheme_Stx *cstx = (Scheme_Stx *)code; if ((cstx->srcloc->col >= 0) || (cstx->srcloc->pos >= 0)) { char buf[50], src[20]; - Scheme_Object *name; + Scheme_Object *name, *bstr; + int convert_backslash = 0; - if (cstx->srcloc->src && SCHEME_PATHP(cstx->srcloc->src)) { - if (SCHEME_BYTE_STRLEN_VAL(cstx->srcloc->src) < 20) - memcpy(src, SCHEME_BYTE_STR_VAL(cstx->srcloc->src), SCHEME_BYTE_STRLEN_VAL(cstx->srcloc->src) + 1); + if (cstx->srcloc->src) { + if (SCHEME_PATHP(cstx->srcloc->src)) { + bstr = cstx->srcloc->src; + /* for generating consistent names on machines with different platform + conventions, convert "\" to "/" */ + convert_backslash = 1; + } else if (SCHEME_CHAR_STRINGP(cstx->srcloc->src)) + bstr = scheme_char_string_to_byte_string(cstx->srcloc->src); + else + bstr = NULL; + } else + bstr = NULL; + + if (bstr) { + if (SCHEME_BYTE_STRLEN_VAL(bstr) < 20) + memcpy(src, SCHEME_BYTE_STR_VAL(bstr), SCHEME_BYTE_STRLEN_VAL(bstr) + 1); else { - memcpy(src, SCHEME_BYTE_STR_VAL(cstx->srcloc->src) + SCHEME_BYTE_STRLEN_VAL(cstx->srcloc->src) - 19, 20); + memcpy(src, SCHEME_BYTE_STR_VAL(bstr) + SCHEME_BYTE_STRLEN_VAL(bstr) - 19, 20); src[0] = '.'; src[1] = '.'; src[2] = '.'; } + if (convert_backslash) { + int i; + for (i = 0; src[i]; i++) { + if (src[i] == '\\') + src[i] = '/'; + } + } } else { return NULL; } diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index fdfdbe689e..7faa4bde50 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -5612,9 +5612,26 @@ static Scheme_Object *do_explode_path(Scheme_Object *p) return explode_path(1, &p); } -Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir) +static Scheme_Object *to_bytes(Scheme_Object *p) { - Scheme_Object *de, *be, *oe; + if (SCHEME_PATHP(p)) + return scheme_make_sized_byte_string(SCHEME_PATH_VAL(p), + SCHEME_PATH_LEN(p), + 1); + else + return p; +} + +Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir, Scheme_Hash_Table *cache) +/* When cache is non-NULL, generate a path or a list of byte strings (suitable for bytecode) */ +{ + Scheme_Object *de, *be, *oe, *orig_obj = obj; + + if (cache) { + de = scheme_hash_get(cache, obj); + if (de) + return de; + } if (SCHEME_PAIRP(dir)) { be = do_explode_path(SCHEME_CAR(dir)); @@ -5644,32 +5661,78 @@ Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir be = SCHEME_CDR(be); } + /* If cache is non-NULL, generate a list of byte strings */ + if (SCHEME_NULLP(oe)) { - a[0] = same_symbol; - obj = scheme_build_path(1, a); + if (cache) { + obj = scheme_null; + } else { + a[0] = same_symbol; + obj = scheme_build_path(1, a); + } } else { obj = SCHEME_CAR(oe); + if (cache) + obj = scheme_make_pair(to_bytes(obj), scheme_null); oe = SCHEME_CDR(oe); } while (SCHEME_PAIRP(oe)) { - a[0] = obj; - a[1] = SCHEME_CAR(oe); - obj = scheme_build_path(2, a); + if (cache) { + obj = scheme_make_pair(to_bytes(SCHEME_CAR(oe)), scheme_null); + } else { + a[0] = obj; + a[1] = SCHEME_CAR(oe); + obj = scheme_build_path(2, a); + } oe = SCHEME_CDR(oe); } + if (cache) + obj = scheme_reverse(obj); + while (!SCHEME_NULLP(be)) { - a[0] = up_symbol; - a[1] = obj; - obj = scheme_build_path(2, a); + if (cache) { + obj = scheme_make_pair(up_symbol, scheme_null); + } else { + a[0] = up_symbol; + a[1] = obj; + obj = scheme_build_path(2, a); + } be = SCHEME_CDR(be); } } + if (cache) + scheme_hash_set(cache, orig_obj, obj); + return obj; } +Scheme_Object *scheme_maybe_build_path(Scheme_Object *base, Scheme_Object *elem) +{ + Scheme_Object *a[2]; + + if (!base) + base = scheme_get_param(scheme_current_config(), MZCONFIG_CURRENT_DIRECTORY); + + if (SAME_OBJ(elem, same_symbol) + || SAME_OBJ(elem, up_symbol)) { + /* ok */ + } else if (SCHEME_BYTE_STRINGP(elem)) { + a[0] = elem; + elem = bytes_to_path_element(1, a); + } else + elem = NULL; + + if (elem) { + a[0] = base; + a[1] = elem; + return scheme_build_path(2, a); + } else + return base; +} + static Scheme_Object *filesystem_root_list(int argc, Scheme_Object *argv[]) { Scheme_Object *first = scheme_null; diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 1230849466..9f17ebb3c3 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -717,15 +717,15 @@ static Scheme_Object *read_quote_syntax(Scheme_Object *obj) #define BOOL(x) (x ? scheme_true : scheme_false) -static int not_relative_path(Scheme_Object *p) +static int not_relative_path(Scheme_Object *p, Scheme_Hash_Table *cache) { Scheme_Object *dir, *rel_p; dir = scheme_get_param(scheme_current_config(), MZCONFIG_WRITE_DIRECTORY); if (SCHEME_TRUEP(dir)) { - rel_p = scheme_extract_relative_to(p, dir); - if (SAME_OBJ(rel_p, p)) + rel_p = scheme_extract_relative_to(p, dir, cache); + if (SCHEME_PATHP(rel_p)) return 1; } @@ -752,7 +752,7 @@ static Scheme_Object *write_compiled_closure(Scheme_Object *obj) /* If MZCONFIG_WRITE_DIRECTORY, drop any non-relative path (which might happen due to function inlining, for example) to avoid embedding absolute paths in bytecode files: */ - || not_relative_path(src)) + || not_relative_path(src, scheme_current_thread->current_mt->path_cache)) && !SCHEME_CHAR_STRINGP(src) && !SCHEME_SYMBOLP(src)) { /* Just keep the name */ diff --git a/racket/src/racket/src/mzmark_print.inc b/racket/src/racket/src/mzmark_print.inc index fa8abafb46..027545ae6b 100644 --- a/racket/src/racket/src/mzmark_print.inc +++ b/racket/src/racket/src/mzmark_print.inc @@ -53,6 +53,7 @@ static int mark_marshal_tables_MARK(void *p, struct NewGC *gc) { gcMARK2(mt->cdata_map, gc); gcMARK2(mt->rn_saved, gc); gcMARK2(mt->shared_offsets, gc); + gcMARK2(mt->path_cache, gc); gcMARK2(mt->sorted_keys, gc); return gcBYTES_TO_WORDS(sizeof(Scheme_Marshal_Tables)); @@ -75,6 +76,7 @@ static int mark_marshal_tables_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(mt->cdata_map, gc); gcFIXUP2(mt->rn_saved, gc); gcFIXUP2(mt->shared_offsets, gc); + gcFIXUP2(mt->path_cache, gc); gcFIXUP2(mt->sorted_keys, gc); return gcBYTES_TO_WORDS(sizeof(Scheme_Marshal_Tables)); diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 7e56ae0bbe..6127359044 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -1830,6 +1830,7 @@ mark_marshal_tables { gcMARK2(mt->cdata_map, gc); gcMARK2(mt->rn_saved, gc); gcMARK2(mt->shared_offsets, gc); + gcMARK2(mt->path_cache, gc); gcMARK2(mt->sorted_keys, gc); size: gcBYTES_TO_WORDS(sizeof(Scheme_Marshal_Tables)); diff --git a/racket/src/racket/src/portfun.c b/racket/src/racket/src/portfun.c index 8a7e4feaa1..87202e62ca 100644 --- a/racket/src/racket/src/portfun.c +++ b/racket/src/racket/src/portfun.c @@ -4991,7 +4991,7 @@ static Scheme_Object *wr_abs_directory_p(int argc, Scheme_Object **argv) Scheme_Object *a, *d, *r; a = abs_directory_p("current-write-relative-directory", SCHEME_CAR(argv[0])); d = abs_directory_p("current-write-relative-directory", SCHEME_CDR(argv[0])); - r = scheme_extract_relative_to(a, d); + r = scheme_extract_relative_to(a, d, NULL); if (SAME_OBJ(a, r)) { scheme_contract_error("current-write-relative-directory", "first path does not extend second path", diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index 21fb216bd6..6c705f55ee 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -2619,13 +2619,17 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, dir = scheme_get_param(scheme_current_config(), MZCONFIG_WRITE_DIRECTORY); if (SCHEME_TRUEP(dir)) - obj = scheme_extract_relative_to(obj, dir); + obj = scheme_extract_relative_to(obj, dir, mt->path_cache); print_compact(pp, CPT_PATH); - - l = SCHEME_PATH_LEN(obj); - print_compact_number(pp, l); - print_this_string(pp, SCHEME_PATH_VAL(obj), 0, l); + if (SCHEME_PATHP(obj)) { + l = SCHEME_PATH_LEN(obj); + print_compact_number(pp, l); + print_this_string(pp, SCHEME_PATH_VAL(obj), 0, l); + } else { + print_compact_number(pp, 0); + print(obj, notdisplay, compact, ht, mt, pp); + } symtab_set(pp, mt, orig_obj); } @@ -2638,7 +2642,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, dir = scheme_get_param(scheme_current_config(), MZCONFIG_WRITE_DIRECTORY); if (SCHEME_TRUEP(dir)) - obj = scheme_extract_relative_to(obj, dir); + obj = scheme_extract_relative_to(obj, dir, mt->path_cache); print_utf8_string(pp, "#^", 0, 2); obj = scheme_make_sized_byte_string(SCHEME_PATH_VAL(obj), @@ -3467,7 +3471,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, if (compact) closed = print(v, notdisplay, 1, NULL, mt, pp); else { - Scheme_Hash_Table *st_refs, *symtab, *reachable_scopes, *intern_map; + Scheme_Hash_Table *st_refs, *symtab, *reachable_scopes, *intern_map, *path_cache; intptr_t *shared_offsets; intptr_t st_len, j, shared_offset, start_offset; @@ -3490,6 +3494,8 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, mt->reachable_scope_stack = scheme_null; symtab = make_hash_table_symtab(); mt->symtab = symtab; + path_cache = scheme_make_hash_table_equal(); + mt->path_cache = path_cache; print_substring(v, notdisplay, 1, NULL, mt, pp, NULL, &slen, 0, NULL); scheme_iterate_reachable_scopes(mt); @@ -3500,6 +3506,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, scheme_current_thread->current_mt = mt; mt->reachable_scopes = reachable_scopes; mt->intern_map = intern_map; + mt->path_cache = path_cache; /* Track which shared values are referenced: */ st_refs = make_hash_table_symtab(); diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 511128c06c..94f944dcaf 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -5025,18 +5025,22 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) { l = read_compact_number(port); RANGE_CHECK_GETS(l); - s = read_compact_chars(port, buffer, BLK_BUF_SIZE, l); - v = scheme_make_sized_path(s, l, l < BLK_BUF_SIZE); - - if (scheme_is_relative_path(SCHEME_PATH_VAL(v), SCHEME_PATH_LEN(v), SCHEME_PLATFORM_PATH_KIND)) { - /* Resolve relative path using the current load-relative directory: */ - if (SCHEME_PATHP(port->relto)) { - Scheme_Object *a[2]; - a[0] = port->relto; - a[1] = v; - v = scheme_build_path(2, a); - } - } + if (l) { + s = read_compact_chars(port, buffer, BLK_BUF_SIZE, l); + v = scheme_make_sized_path(s, l, l < BLK_BUF_SIZE); + } else { + Scheme_Object *elems; + elems = read_compact(port, 0); + if (SCHEME_PATHP(port->relto)) { + /* Resolve relative path using the current load-relative directory: */ + v = port->relto; + } else + v = scheme_maybe_build_path(NULL, scheme_false); + while (SCHEME_PAIRP(elems)) { + v = scheme_maybe_build_path(v, SCHEME_CAR(elems)); + elems = SCHEME_CDR(elems); + } + } } break; case CPT_CLOSURE: diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 1066d5275e..a44a82d6b3 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -3348,6 +3348,7 @@ typedef struct Scheme_Marshal_Tables { Scheme_Object **cdata_map; /* for delay-load wrappers */ int cdata_counter; /* used with cdata_map */ intptr_t *shared_offsets; /* set in second pass */ + Scheme_Hash_Table *path_cache; /* cache for path-to-relative resolution */ intptr_t sorted_keys_count; intptr_t inspector_counter; /* for deterministic symbol allocation */ Scheme_Object **sorted_keys; @@ -3920,7 +3921,7 @@ Scheme_Object *scheme_get_run_cmd(void); Scheme_Object *scheme_get_fd_identity(Scheme_Object *port, intptr_t fd, char *path, int noerr); -Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir); +Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir, Scheme_Hash_Table *cache); Scheme_Object *scheme_find_links_path(int argc, Scheme_Object *argv[]); @@ -4200,6 +4201,8 @@ Scheme_Object *scheme_intern_exact_parallel_symbol(const char *name, uintptr_t l Scheme_Object *scheme_symbol_append(Scheme_Object *s1, Scheme_Object *s2); Scheme_Object *scheme_copy_list(Scheme_Object *l); +Scheme_Object *scheme_append_strings(Scheme_Object *s1, Scheme_Object *s2); + void scheme_reset_hash_table(Scheme_Hash_Table *ht, int *history); XFORM_NONGCING Scheme_Object *scheme_regexp_source(Scheme_Object *re); @@ -4214,6 +4217,9 @@ int scheme_regexp_match_p(Scheme_Object *regexp, Scheme_Object *target); Scheme_Object *scheme_gensym(Scheme_Object *base); Scheme_Object *scheme_symbol_to_string(Scheme_Object *sym); + +Scheme_Object *scheme_maybe_build_path(Scheme_Object *base, Scheme_Object *elem); + #ifdef SCHEME_BIG_ENDIAN # define MZ_UCS4_NAME "UCS-4BE" #else diff --git a/racket/src/racket/src/string.c b/racket/src/racket/src/string.c index 4d31ff0a30..168ff2cf75 100644 --- a/racket/src/racket/src/string.c +++ b/racket/src/racket/src/string.c @@ -1044,6 +1044,14 @@ scheme_make_locale_string(const char *chars) return scheme_byte_string_to_char_string_locale(scheme_make_byte_string((char *)chars)); } +Scheme_Object *scheme_append_strings(Scheme_Object *s1, Scheme_Object *s2) +{ + Scheme_Object *a[2]; + a[0] = s1; + a[1] = s2; + return string_append(2, a); +} + /**********************************************************************/ /* index helpers */ /**********************************************************************/ diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 42ad41249c..97083f6763 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -6167,12 +6167,30 @@ static void lift_common_wraps(Scheme_Object *l, int cnt, int tail) } } +static Scheme_Object *srcloc_path_to_string(Scheme_Object *p) +{ + Scheme_Object *base, *name, *dir_name; + int isdir; + + name = scheme_split_path(SCHEME_PATH_VAL(p), SCHEME_PATH_LEN(p), &base, &isdir, SCHEME_PLATFORM_PATH_KIND); + if (SCHEME_PATHP(name) && SCHEME_PATHP(base)) { + dir_name = scheme_split_path(SCHEME_PATH_VAL(base), SCHEME_PATH_LEN(base), &base, &isdir, SCHEME_PLATFORM_PATH_KIND); + if (SCHEME_PATHP(dir_name)) + name = scheme_append_strings(scheme_path_to_char_string(dir_name), + scheme_append_strings(scheme_make_utf8_string("/"), + scheme_path_to_char_string(name))); + else + name = scheme_path_to_char_string(name); + return scheme_append_strings(scheme_make_utf8_string(".../"), name); + } else if (SCHEME_PATHP(name)) + return scheme_path_to_char_string(name); + else + return scheme_false; +} + static Scheme_Object *convert_srcloc(Scheme_Stx_Srcloc *srcloc, Scheme_Hash_Tree *props, Scheme_Marshal_Tables *mt) { - Scheme_Object *vec, *paren; - - if (!srcloc) - return scheme_false; + Scheme_Object *vec, *paren, *src, *dir; if (props) { paren = scheme_hash_tree_get(props, scheme_paren_shape_symbol); @@ -6181,8 +6199,40 @@ static Scheme_Object *convert_srcloc(Scheme_Stx_Srcloc *srcloc, Scheme_Hash_Tree } else paren = NULL; + if ((!srcloc || (SCHEME_FALSEP(srcloc->src) + && (srcloc->line < 0) + && (srcloc->col < 0) + && (srcloc->pos < 0))) + && !paren) + return scheme_false; + + if (!srcloc) + srcloc = empty_srcloc; + + src = srcloc->src; + if (SCHEME_PATHP(src)) { + /* To make paths portable and to avoid full paths, check whether the + path can be made relative (in which case it is turned into a list + of byte strings). If not, convert to a string using only the + last couple of path elements. */ + dir = scheme_get_param(scheme_current_config(), + MZCONFIG_WRITE_DIRECTORY); + if (SCHEME_TRUEP(dir)) + src = scheme_extract_relative_to(src, dir, mt->path_cache); + if (SCHEME_PATHP(src)) { + src = scheme_hash_get(mt->path_cache, scheme_box(srcloc->src)); + if (!src) { + src = srcloc_path_to_string(srcloc->src); + scheme_hash_set(mt->path_cache, scheme_box(srcloc->src), src); + } + } else { + /* use the path directly and let the printer make it relative */ + src = srcloc->src; + } + } + vec = scheme_make_vector((paren ? 6 : 5), NULL); - SCHEME_VEC_ELS(vec)[0] = srcloc->src; + SCHEME_VEC_ELS(vec)[0] = src; SCHEME_VEC_ELS(vec)[1] = scheme_make_integer(srcloc->line); SCHEME_VEC_ELS(vec)[2] = scheme_make_integer(srcloc->col); SCHEME_VEC_ELS(vec)[3] = scheme_make_integer(srcloc->pos); From efe056f18df8b57dbb419fb899bbe122606a8691 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Sep 2015 12:55:44 -0600 Subject: [PATCH 140/381] update documentation for preserved syntax-object source locations --- .../scribblings/raco/zo-struct.scrbl | 6 ++++- .../scribblings/reference/stx-ops.scrbl | 26 +++++++++---------- .../scribblings/reference/stx-props.scrbl | 5 ++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl index a400ec0dbe..7cd3875368 100644 --- a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl +++ b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl @@ -594,9 +594,13 @@ binding, constructor, etc.} @defstruct+[(stx-obj zo) ([datum any/c] [wrap wrap?] + [srcloc (or/c #f srcloc?)] + [props (hash/c symbol? any/c)] [tamper-status (or/c 'clean 'armed 'tainted)])]{ Represents a syntax object, where @racket[wrap] contains lexical - information and @racket[tamper-status] is taint information. When the + information, @racket[srcloc] is the source location, + @racket[props] contains preserved properties, + and @racket[tamper-status] is taint information. When the @racket[datum] part is itself compound, its pieces are wrapped as @racket[stx-obj]s, too. diff --git a/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl b/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl index 9cde3b6129..9ba322a818 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-ops.scrbl @@ -38,9 +38,7 @@ Returns @racket[#t] if @racket[v] is a @tech{syntax object} and Returns the source for the @tech{syntax object} @racket[stx], or @racket[#f] if none is known. The source is represented by an arbitrary value (e.g., one passed to @racket[read-syntax]), but it is typically a file -path string. Source-location information is dropped for a syntax -object that is marshaled as part of compiled code; see also -@racket[current-compile].} +path string.} @defproc[(syntax-line [stx syntax?]) @@ -50,8 +48,7 @@ Returns the line number (positive exact integer) for the start of the @tech{syntax object} in its source, or @racket[#f] if the line number or source is unknown. The result is @racket[#f] if and only if @racket[(syntax-column stx)] produces @racket[#f]. See also -@secref["linecol"], and see @racket[syntax-source] for information -about marshaling compiled @tech{syntax object}s.} +@secref["linecol"].} @defproc[(syntax-column [stx syntax?]) @@ -61,8 +58,7 @@ Returns the column number (non-negative exact integer) for the start of the @tech{syntax object} in its source, or @racket[#f] if the source column is unknown. The result is @racket[#f] if and only if @racket[(syntax-line stx)] produces @racket[#f]. See also -@secref["linecol"], and see @racket[syntax-source] for information -about marshaling compiled @tech{syntax object}s.} +@secref["linecol"].} @defproc[(syntax-position [stx syntax?]) @@ -70,9 +66,7 @@ about marshaling compiled @tech{syntax object}s.} Returns the character position (positive exact integer) for the start of the @tech{syntax object} in its source, or @racket[#f] if the source -position is unknown. See also @secref["linecol"], and see -@racket[syntax-source] for information about marshaling compiled -@tech{syntax object}s.} +position is unknown. See also @secref["linecol"].} @defproc[(syntax-span [stx syntax?]) @@ -80,8 +74,7 @@ position is unknown. See also @secref["linecol"], and see Returns the span (non-negative exact integer) in characters of the @tech{syntax object} in its source, or @racket[#f] if the span is -unknown. See also @racket[syntax-source] for information about -marshaling compiled @tech{syntax object}s.} +unknown.} @defproc[(syntax-original? [stx syntax?]) boolean?]{ @@ -95,14 +88,19 @@ object was introduced by a syntax transformer; see This predicate can be used to distinguish @tech{syntax object}s in an expanded expression that were directly present in the original expression, as -opposed to @tech{syntax object}s inserted by macros.} +opposed to @tech{syntax object}s inserted by macros. + +The (hidden) property to represent original syntax is dropped for a +syntax object that is marshaled as part of compiled code; see also +@racket[current-compile].} @defproc[(syntax-source-module [stx syntax?] [source? any/c #f]) (or/c module-path-index? symbol? path? resolved-module-path? #f)]{ Returns an indication of the module whose source contains -@racket[stx], or @racket[#f] if @racket[stx] has no source module. If +@racket[stx], or @racket[#f] if no source module for @racket[stx] +can be inferred from its lexical context. If @racket[source?] is @racket[#f], then result is a module path index or symbol (see @secref["modpathidx"]) or a @tech{resolved module path}; if @racket[source?] is true, the result is a path or symbol corresponding to the loaded module's diff --git a/pkgs/racket-doc/scribblings/reference/stx-props.scrbl b/pkgs/racket-doc/scribblings/reference/stx-props.scrbl index 23f316f5cb..694abc4578 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-props.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-props.scrbl @@ -6,8 +6,9 @@ Every syntax object has an associated @deftech{syntax property} list, which can be queried or extended with @racket[syntax-property]. Properties are not preserved for a -@racket[syntax-quoted] syntax object in a compiled form that is -marshaled to a byte string. +syntax object in a compiled form that is +marshaled to a byte string or @filepath{.zo} file, except for a @racket['paren-shape] +property value of @racket[#\[] or @racket[#\{]. In @racket[read-syntax], the reader attaches a @racket['paren-shape] property to any pair or vector syntax object generated from parsing a From 322714f123a9884e288c2f1156ba6d56cf58cf2e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Sep 2015 13:15:03 -0600 Subject: [PATCH 141/381] untar and unzip: reject paths that contain ".." Also, for unzip, reject absolute paths. --- racket/collects/file/private/check-path.rkt | 11 +++++++++++ racket/collects/file/untar.rkt | 6 +++--- racket/collects/file/unzip.rkt | 7 +++++-- 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 racket/collects/file/private/check-path.rkt diff --git a/racket/collects/file/private/check-path.rkt b/racket/collects/file/private/check-path.rkt new file mode 100644 index 0000000000..90a4d219ab --- /dev/null +++ b/racket/collects/file/private/check-path.rkt @@ -0,0 +1,11 @@ +#lang racket/base + +(provide check-unpack-path) + +(define (check-unpack-path who filename) + (when (absolute-path? filename) + (error who "won't extract a file with an absolute path\n path: ~e" filename)) + (for ([e (in-list (explode-path filename))]) + (when (eq? e 'up) + (error who "won't extract a file with an up-directory element\n path: ~e" filename)))) + diff --git a/racket/collects/file/untar.rkt b/racket/collects/file/untar.rkt index 10a35216d6..bce385eb9b 100644 --- a/racket/collects/file/untar.rkt +++ b/racket/collects/file/untar.rkt @@ -2,7 +2,8 @@ (require racket/file racket/contract/base racket/port - "private/strip-prefix.rkt") + "private/strip-prefix.rkt" + "private/check-path.rkt") (provide (contract-out @@ -78,8 +79,7 @@ name (bytes-append prefix #"/" name))) name)))) - (when (absolute-path? base-filename) - (error 'untar "won't extract a file with an absolute path: ~e" base-filename)) + (check-unpack-path 'untar base-filename) (define stripped-filename (strip-prefix base-filename strip-count)) (define filename (and stripped-filename (if dest diff --git a/racket/collects/file/unzip.rkt b/racket/collects/file/unzip.rkt index fa962f3f06..189afcf059 100644 --- a/racket/collects/file/unzip.rkt +++ b/racket/collects/file/unzip.rkt @@ -4,7 +4,8 @@ racket/file racket/date file/gunzip - "private/strip-prefix.rkt") + "private/strip-prefix.rkt" + "private/check-path.rkt") (provide (struct-out exn:fail:unzip:no-such-entry) @@ -359,7 +360,9 @@ (define make-filesystem-entry-reader (lambda (#:dest [dest-dir #f] #:strip-count [strip-count 0] #:exists [flag 'error]) (lambda (name dir? in [timestamp #f]) - (let* ([base-path (strip-prefix (bytes->path name) strip-count)] + (define path (bytes->path name)) + (check-unpack-path 'unzip path) + (let* ([base-path (strip-prefix path strip-count)] [path (and base-path (if dest-dir (build-path dest-dir base-path) From 8ee717520fa6c487b03fa80df17bcab55e55529a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Sep 2015 16:14:20 -0600 Subject: [PATCH 142/381] fix `sync` when resumed after a break exception This repair adjusts the bug fix of commit 769ad3e98. That older commit ensured that `sync/enable-break` doesn't both break and accept a channel message or semaphore wait. But it effectively disables those actions if the break is continued. Instead of (partially!) ending the `sync` get out of semaphore and channel queues so that no event can be selected during the break, and then get back in line if the break is continued. --- pkgs/racket-test-core/tests/racket/sync.rktl | 32 ++++++++++++ racket/src/racket/src/schpriv.h | 2 + racket/src/racket/src/sema.c | 5 ++ racket/src/racket/src/struct.c | 7 +++ racket/src/racket/src/thread.c | 52 +++++++++++++++++++- 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/sync.rktl b/pkgs/racket-test-core/tests/racket/sync.rktl index ea4dbc47c5..aeb6627bb0 100644 --- a/pkgs/racket-test-core/tests/racket/sync.rktl +++ b/pkgs/racket-test-core/tests/racket/sync.rktl @@ -1403,6 +1403,38 @@ (break-thread t) (test t sync t)) +;; ---------------------------------------- +;; result from a break during `sync` + +(let () + (define (try wrap val) + (for ([tsync (list sync sync/enable-break)]) + (define ch (make-channel)) + (define got #f) + (define t (thread (lambda () + (define nack #f) + (call-with-exception-handler + (lambda (exn) + (test #f sync/timeout 0 nack) + (if (exn:break? exn) + ((exn:break-continuation exn)) + exn)) + (lambda () + (set! got (tsync (nack-guard-evt + (lambda (n) + (set! nack n) + (wrap ch)))))))))) + (sync (system-idle-evt)) + (break-thread t) + (sync (system-idle-evt)) + (channel-put ch val) + (sync t) + (test val values got))) + + (try values 'ok-channel) + (try (lambda (c) (choice-evt c (alarm-evt (+ 10000 (current-milliseconds))))) + 'ok-channel+alarm)) + ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index a44a82d6b3..12580e462d 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -787,6 +787,7 @@ void scheme_syncing_needs_wakeup(struct Syncing *s, void *fds); void scheme_escape_during_sync(struct Syncing *syncing); Scheme_Object *scheme_syncing_result(struct Syncing *syncing, int tailok); +struct Syncing *scheme_replace_evt_get(Scheme_Object *active_replace); struct Syncing *scheme_replace_evt_nack(Scheme_Object *active_replace); struct Syncing *scheme_replace_evt_needs_wakeup(Scheme_Object *o); @@ -1992,6 +1993,7 @@ Scheme_Object *scheme_do_chaperone_evt(const char*, int, int, Scheme_Object *arg extern Scheme_Object *scheme_always_ready_evt; void scheme_get_outof_line(Scheme_Channel_Syncer *ch_w); +void scheme_get_back_into_line(Scheme_Channel_Syncer *ch_w); void scheme_post_syncing_nacks(Syncing *syncing); int scheme_try_channel_get(Scheme_Object *ch); diff --git a/racket/src/racket/src/sema.c b/racket/src/racket/src/sema.c index 9248347b89..49ac297139 100644 --- a/racket/src/racket/src/sema.c +++ b/racket/src/racket/src/sema.c @@ -544,6 +544,11 @@ void scheme_get_outof_line(Scheme_Channel_Syncer *ch_w) get_outof_line((Scheme_Sema *)ch_w->obj, ch_w); } +void scheme_get_back_into_line(Scheme_Channel_Syncer *ch_w) +{ + get_into_line((Scheme_Sema *)ch_w->obj, ch_w); +} + static int try_channel(Scheme_Sema *sema, Syncing *syncing, int pos, Scheme_Object **result) { if (SCHEME_CHANNELP(sema)) { diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index 8007b205f2..dd43c2836d 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -4191,6 +4191,13 @@ Syncing *scheme_replace_evt_nack(Scheme_Object *o) return s; } +Syncing *scheme_replace_evt_get(Scheme_Object *o) +{ + Active_Replace_Evt *a = (Active_Replace_Evt *)o; + + return a->syncing; +} + /*========================================================================*/ /* struct op maker */ /*========================================================================*/ diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 74934e86a3..7f47807b87 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -436,6 +436,7 @@ static void suspend_thread(Scheme_Thread *p); static int check_sleep(int need_activity, int sleep_now); static int syncing_ready(Syncing *syncing, Scheme_Schedule_Info *sinfo); +static void get_outof_or_into_lines(Syncing *syncing, int get_out); static void remove_thread(Scheme_Thread *r); static void exit_or_escape(Scheme_Thread *p); @@ -4606,8 +4607,10 @@ static void raise_break(Scheme_Thread *p) p->external_break = 0; if (p->blocker && (p->block_check == (Scheme_Ready_Fun)syncing_ready)) { - /* Get out of lines for channels, etc., before calling a break exn handler. */ - scheme_post_syncing_nacks((Syncing *)p->blocker); + /* Get out of lines for channels, etc., before calling a break exn handler. + This is only strictly necessary for `sync/enable-break`, which wants + to provide a sync-or-break guarantee, but we do it always for consistency. */ + get_outof_or_into_lines((Syncing *)p->blocker, 1); } save_thread_schedule_state(p, &ssr, 0); @@ -4626,6 +4629,11 @@ static void raise_break(Scheme_Thread *p) /* Continue from break... */ restore_thread_schedule_state(p, &ssr, 0); + + if (p->blocker && (p->block_check == (Scheme_Ready_Fun)syncing_ready)) { + /* Get back into lines for channels, etc. */ + get_outof_or_into_lines((Syncing *)p->blocker, 0); + } } static void escape_to_kill(Scheme_Thread *p) @@ -7002,6 +7010,46 @@ static void post_syncing_nacks(Syncing *syncing, int as_escape) } while (syncing); } +static void get_outof_or_into_lines(Syncing *syncing, int get_out) +{ + int i, c; + Scheme_Object *syncs = NULL; + Syncing *next; + + if (syncing->result) { + /* already done, so no need to adjust lines */ + return; + } + + do { + if (syncing->set) { + c = syncing->set->argc; + + for (i = 0; i < c; i++) { + if (SAME_TYPE(SCHEME_TYPE(syncing->set->argv[i]), scheme_channel_syncer_type)) { + if (get_out) + scheme_get_outof_line((Scheme_Channel_Syncer *)syncing->set->argv[i]); + else + scheme_get_back_into_line((Scheme_Channel_Syncer *)syncing->set->argv[i]); + } + else if (SAME_TYPE(SCHEME_TYPE(syncing->set->argv[i]), scheme_active_replace_evt_type)) { + /* Handle active_replace_evt specially to avoid stack overflow: */ + next = scheme_replace_evt_get(syncing->set->argv[i]); + if (next) + syncs = scheme_make_raw_pair((Scheme_Object *)next, syncs); + } + } + } + + if (!syncs) + syncing = NULL; + else { + syncing = (Syncing *)SCHEME_CAR(syncs); + syncs = SCHEME_CDR(syncs); + } + } while (syncing); +} + void scheme_post_syncing_nacks(Syncing *syncing) { post_syncing_nacks(syncing, 0); From ddb683e1f2f22d64cd706118ac072aa5694b97c5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Sep 2015 17:58:34 -0600 Subject: [PATCH 143/381] unbreak `compile-directory` --- racket/collects/compiler/compiler.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/collects/compiler/compiler.rkt b/racket/collects/compiler/compiler.rkt index d6728b5e07..a6ff50af08 100644 --- a/racket/collects/compiler/compiler.rkt +++ b/racket/collects/compiler/compiler.rkt @@ -150,6 +150,7 @@ (let ([p* (build-path dir p)]) (if (and (directory-exists? p*) (not (member p omit-paths))) (compile-directory-visitor p* (c-get-info/full p*) worker omit-root + #:has-module-suffix? has-module-suffix? #:verbose verbose? #:skip-path orig-skip-path #:skip-paths orig-skip-paths From 9b7e1767ddf9b77d74203a64fcb1618c07bef8bc Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Tue, 25 Aug 2015 17:01:04 -0500 Subject: [PATCH 144/381] Add syntax property with static init-depend information to compound-unit/infer results --- .../racket/private/unit-compiletime.rkt | 17 ++++++- racket/collects/racket/unit.rkt | 49 ++++++++++--------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/racket/collects/racket/private/unit-compiletime.rkt b/racket/collects/racket/private/unit-compiletime.rkt index c1b66fd30f..916b869e83 100644 --- a/racket/collects/racket/private/unit-compiletime.rkt +++ b/racket/collects/racket/private/unit-compiletime.rkt @@ -22,7 +22,8 @@ map-sig split-requires split-requires* apply-mac complete-exports complete-imports check-duplicate-subs process-spec make-relative-introducer - bind-at) + bind-at + build-init-depend-property) (define-syntax (apply-mac stx) (syntax-case stx () @@ -594,3 +595,17 @@ sstx (cons unbox-stx #'x) sstx)])))) + +;; This utility function returns a list of natural numbers for use as a syntax +;; property needed to support units in Typed Racket +(define (build-init-depend-property init-depends imports) + ;; Typed Racket does not support tagged imports or exports + ;; so drop the tags from init-depends and imports + (let ([id-sigs (map cdr init-depends)] + [import-sigs (map cdr imports)]) + (let loop ([i 0] [imports import-sigs]) + (cond + [(null? imports) '()] + [else (if (member (car imports) id-sigs free-identifier=?) + (cons i (loop (add1 i) (cdr imports))) + (loop (add1 i) (cdr imports)))])))) \ No newline at end of file diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index 950dcf46c2..65c18bf01f 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -1645,29 +1645,34 @@ (syntax->list #'((((sub-in-key sub-in-code) ...) ...) ...)))) ) (values - (quasisyntax/loc (error-syntax) - (let ([deps '()] - [sub-tmp sub-exp] ...) - check-sub-exp ... - (make-unit - 'name - (vector-immutable - (cons 'import-name - (vector-immutable import-key ...)) - ...) - (vector-immutable - (cons 'export-name - (vector-immutable export-key ...)) - ...) - deps - (lambda () - (let-values ([(sub-tmp sub-export-table-tmp) ((unit-go sub-tmp))] + (syntax-property + (quasisyntax/loc (error-syntax) + (let ([deps '()] + [sub-tmp sub-exp] ...) + check-sub-exp ... + (make-unit + 'name + (vector-immutable + (cons 'import-name + (vector-immutable import-key ...)) + ...) + (vector-immutable + (cons 'export-name + (vector-immutable export-key ...)) + ...) + deps + (lambda () + (let-values ([(sub-tmp sub-export-table-tmp) ((unit-go sub-tmp))] + ...) + (values (lambda (import-table-id) + (void) + (sub-tmp (equal-hash-table sub-in-key-code-workaround ...)) ...) - (values (lambda (import-table-id) - (void) - (sub-tmp (equal-hash-table sub-in-key-code-workaround ...)) - ...) - (unit-export ((export-key ...) export-code) ...))))))) + (unit-export ((export-key ...) export-code) ...))))))) + 'tr:inferred-init-depend-property + (build-init-depend-property + static-dep-info + (map syntax-e (syntax->list #'((import-tag . import-sigid) ...))))) (map syntax-e (syntax->list #'((import-tag . import-sigid) ...))) (map syntax-e (syntax->list #'((export-tag . export-sigid) ...))) static-dep-info)))))) From b3fe6bb778481c0fdb838cac2bd2111f008c3742 Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Sun, 30 Aug 2015 16:44:18 -0500 Subject: [PATCH 145/381] Handle tags in case this syntax-property may have uses outside of Typed Racket --- .../racket/private/unit-compiletime.rkt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/racket/collects/racket/private/unit-compiletime.rkt b/racket/collects/racket/private/unit-compiletime.rkt index 916b869e83..343e71619a 100644 --- a/racket/collects/racket/private/unit-compiletime.rkt +++ b/racket/collects/racket/private/unit-compiletime.rkt @@ -599,13 +599,10 @@ ;; This utility function returns a list of natural numbers for use as a syntax ;; property needed to support units in Typed Racket (define (build-init-depend-property init-depends imports) - ;; Typed Racket does not support tagged imports or exports - ;; so drop the tags from init-depends and imports - (let ([id-sigs (map cdr init-depends)] - [import-sigs (map cdr imports)]) - (let loop ([i 0] [imports import-sigs]) - (cond - [(null? imports) '()] - [else (if (member (car imports) id-sigs free-identifier=?) - (cons i (loop (add1 i) (cdr imports))) - (loop (add1 i) (cdr imports)))])))) \ No newline at end of file + (define (sig=? s1 s2) + (and (eq? (syntax-e (car s1)) (car s2)) + (free-identifier=? (cdr s1) (cdr s2)))) + (for/list ([import (in-list imports)] + [index (in-naturals)] + #:when (member import init-depends sig=?)) + index)) From 7b513e11031714e52341686a923e046fd6b6febb Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Mon, 31 Aug 2015 11:28:27 -0500 Subject: [PATCH 146/381] Internal documentation for init-depend syntax property --- racket/collects/racket/private/unit-compiletime.rkt | 2 ++ racket/collects/racket/unit.rkt | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/racket/collects/racket/private/unit-compiletime.rkt b/racket/collects/racket/private/unit-compiletime.rkt index 343e71619a..8de0501209 100644 --- a/racket/collects/racket/private/unit-compiletime.rkt +++ b/racket/collects/racket/private/unit-compiletime.rkt @@ -598,6 +598,8 @@ ;; This utility function returns a list of natural numbers for use as a syntax ;; property needed to support units in Typed Racket +;; Each number in the list is an index into a unit's list of imports signifying +;; that the import at that index is also an init-dependency of the unit (define (build-init-depend-property init-depends imports) (define (sig=? s1 s2) (and (eq? (syntax-e (car s1)) (car s2)) diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index 65c18bf01f..ba6ae8dac6 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -1645,6 +1645,10 @@ (syntax->list #'((((sub-in-key sub-in-code) ...) ...) ...)))) ) (values + ;; Attach a syntax-property containing indices of init-depends signatures + ;; for this compound unit. Although this property is attached to all + ;; compound-units, it is only meaningful when the compound unit was + ;; created via compound-unit/infer (syntax-property (quasisyntax/loc (error-syntax) (let ([deps '()] From dc19e9c9b2e257ed1acc225840654ca28074989a Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Mon, 31 Aug 2015 14:24:56 -0500 Subject: [PATCH 147/381] Clarify syntax property further --- racket/collects/racket/unit.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index ba6ae8dac6..2933f4e2fd 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -1648,7 +1648,9 @@ ;; Attach a syntax-property containing indices of init-depends signatures ;; for this compound unit. Although this property is attached to all ;; compound-units, it is only meaningful when the compound unit was - ;; created via compound-unit/infer + ;; created via compound-unit/infer. Only the `inferred` dependencies + ;; will appear in this syntax property, when no inference occurs the property + ;; will contain an empty list. (syntax-property (quasisyntax/loc (error-syntax) (let ([deps '()] From 6e5d443d7d5c70bc44f43668f2f2e72ba2936d4a Mon Sep 17 00:00:00 2001 From: Daniel Feltey Date: Tue, 1 Sep 2015 15:34:31 -0500 Subject: [PATCH 148/381] Rename syntax property to avoid a name suggesting it is only useful for Typed Racket --- racket/collects/racket/unit.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index 2933f4e2fd..2bbc53e413 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -1675,7 +1675,7 @@ (sub-tmp (equal-hash-table sub-in-key-code-workaround ...)) ...) (unit-export ((export-key ...) export-code) ...))))))) - 'tr:inferred-init-depend-property + 'inferred-init-depends (build-init-depend-property static-dep-info (map syntax-e (syntax->list #'((import-tag . import-sigid) ...))))) From 053aae7b593991d038bb689995a64d3cb8e1af8a Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 3 Sep 2015 14:08:02 -0500 Subject: [PATCH 149/381] Prefix property name --- racket/collects/racket/unit.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/unit.rkt b/racket/collects/racket/unit.rkt index 2bbc53e413..3bf4e8b180 100644 --- a/racket/collects/racket/unit.rkt +++ b/racket/collects/racket/unit.rkt @@ -1675,7 +1675,7 @@ (sub-tmp (equal-hash-table sub-in-key-code-workaround ...)) ...) (unit-export ((export-key ...) export-code) ...))))))) - 'inferred-init-depends + 'unit:inferred-init-depends (build-init-depend-property static-dep-info (map syntax-e (syntax->list #'((import-tag . import-sigid) ...))))) From 24592f78fc67ca79ed8f0f810a85c7a9ff4e057f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Sep 2015 07:49:46 -0600 Subject: [PATCH 150/381] ffi/unsafe/objc: add support for blocks Also add some functions for manipualting classes and objects. --- pkgs/base/info.rkt | 2 +- .../racket-doc/scribblings/foreign/objc.scrbl | 50 +++++++++++++ racket/collects/ffi/unsafe/objc.rkt | 71 ++++++++++++++++++- racket/src/racket/src/schvers.h | 4 +- 4 files changed, 122 insertions(+), 5 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index af45814da3..2f61c6306d 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.13") +(define version "6.2.900.14") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/foreign/objc.scrbl b/pkgs/racket-doc/scribblings/foreign/objc.scrbl index 56a18d406f..6a52571c9d 100644 --- a/pkgs/racket-doc/scribblings/foreign/objc.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/objc.scrbl @@ -269,6 +269,56 @@ Check whether @racket[subcls] is @racket[cls] or a subclass. @history[#:added "6.1.0.5"]} + +@defproc[(objc-get-class [obj _id]) _Class]{ + +Extract the class of @racket[obj]. + +@history[#:added "6.2.900.14"]} + + +@defproc[(objc-set-class! [obj _id] [cls _Class]) void?]{ + +Changes the class of @racket[obj] to @racket[cls]. The object's +existing representation must be compatible with the new class. + +@history[#:added "6.2.900.14"]} + + +@defproc[(objc-get-superclass [cls _Class]) _Class]{ + +Returns the superclass of @racket[cls]. + +@history[#:added "6.2.900.14"]} + + +@defproc[(objc-dispose-class [cls _Class]) void?]{ + +Destroys @racket[cls], which must have no existing instances or +subclasses. + +@history[#:added "6.2.900.14"]} + + +@defproc[(objc-block [function-type? ctype] + [proc procedure?] + [#:keep keep (box/c list?)]) + cpointer?]{ + +Wraps a Racket function @racket[proc] as an Objective-C block. The +procedure must accept an initial pointer argument that is the ``self'' +argument for the block, and that extra argument must be included in +the given @racket[function-type]. + +Extra records that are allocated to implement the block are added to +the list in @racket[keep], which might also be included in +@racket[function-type] through a @racket[#:keep] option to +@racket[_fun]. The pointers registered in @racket[keep] must be +retained as long as the block remains in use. + +@history[#:added "6.2.900.14"]} + + @; ---------------------------------------------------------------------- @section{Raw Runtime Functions} diff --git a/racket/collects/ffi/unsafe/objc.rkt b/racket/collects/ffi/unsafe/objc.rkt index 6eed6ea1a3..5b906398b2 100644 --- a/racket/collects/ffi/unsafe/objc.rkt +++ b/racket/collects/ffi/unsafe/objc.rkt @@ -149,6 +149,13 @@ #f))]) (cast new _objc_class-pointer _Class))) +(define (dispose-class-pair-the-hard-way c-id) + (define c (cast _Class _objc_class-pointer)) + (define meta (cast _pointer _objc_class-pointer)) + (free (objc_class-name c)) + (free (objc_class-isa c)) + (free c)) + (define (add-ivar-the-hard-way class field-name field-name-type) (let* ([class (cast class _Class _objc_class-pointer)] [ivars (or (objc_class-ivars class) @@ -218,6 +225,8 @@ (define-objc objc_allocateClassPair (_fun _Class _string _long -> _Class) #:fail (lambda () #f)) +(define-objc objc_disposeClassPair (_fun _Class -> _void) + #:fail (lambda () #f)) (define-objc objc_registerClassPair (_fun _Class -> _void) #:fail (lambda () #f)) @@ -226,6 +235,8 @@ (define-objc object_getClass (_fun _id -> _Class) #:fail (lambda () #f)) +(define-objc object_setClass (_fun _id _Class -> _void) + #:fail (lambda () #f)) (define-objc class_addMethod/raw (_fun _Class _SEL _fpointer _string -> _BOOL) #:c-id class_addMethod @@ -567,7 +578,8 @@ (provide define-objc-class define-objc-mixin - self super-tell) + self super-tell + objc-dispose-class) (define-for-syntax ((check-id stx what) id) (unless (identifier? id) @@ -674,6 +686,11 @@ (objc_allocateClassPair superclass-id id-str 0) (allocate-class-pair-the-hard-way superclass-id id-str))) +(define (dispose-class-pair c-id) + (if objc_disposeClassPair + (objc_disposeClassPair c-id) + (dispose-class-pair-the-hard-way c-id))) + (define (register-class-pair id) (if objc_registerClassPair (objc_registerClassPair id) @@ -689,6 +706,11 @@ (object_getClass id) (ptr-ref id _Class))) +(define (object-set-class! id c-id) + (if object_setClass + (object_setClass id c-id) + (ptr-set! id _Class c-id))) + (define (layout->string l) (case l [(uint8) "C"] @@ -874,10 +896,16 @@ #'((make-objc_super self super-class)) #'(method/arg ...))])) +(define (objc-dispose-class c) + (dispose-class-pair c)) + ;; -------------------------------------------------- (provide objc-is-a? - objc-subclass?) + objc-subclass? + objc-get-class + objc-set-class! + objc-get-superclass) (define-objc class_getSuperclass (_fun _Class -> _Class)) @@ -890,6 +918,12 @@ (and pc (objc-subclass? pc c))))) +(define (objc-get-class v) (object-get-class v)) +(define (objc-set-class! v c) (object-set-class! v c)) + +(define (objc-get-superclass c) + (class_getSuperclass c)) + ;; -------------------------------------------------- (define-objc class_getInstanceMethod (_fun _Class _SEL -> _Method)) @@ -898,3 +932,36 @@ (set-objc_method-method_imp! (cast meth _Method _objc_method-pointer) (function-ptr imp _IMP))))) + +;; -------------------------------------------------- + +(provide objc-block) + +(define-cstruct _block ([isa _pointer] + [flags _int] + [reserved _int] + [invoke _fpointer] + [descriptor _pointer]) + #:malloc-mode 'atomic-interior) + +(define-cstruct _block-desc ([reserved _ulong] + [size _ulong]) + #:malloc-mode 'atomic-interior) + +(define-objc _NSConcreteGlobalBlock _pointer + #:fail (lambda () #f)) + +(define (objc-block type proc #:keep keep) + (unless _NSConcreteGlobalBlock + (error 'objc-block "unsupported")) + + (define desc + (make-block-desc 0 (ctype-sizeof _block))) + (define blk + (make-block _NSConcreteGlobalBlock + (arithmetic-shift 3 28) + 0 + (cast proc type _fpointer) + desc)) + (set-box! keep (list* blk desc (unbox keep))) + blk) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 0e9f6a01e0..06e21322b8 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.13" +#define MZSCHEME_VERSION "6.2.900.14" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 13 +#define MZSCHEME_VERSION_W 14 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 16c198805be3e4945496f2ba54e7b4638c4e2d38 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Sep 2015 10:23:57 -0600 Subject: [PATCH 151/381] prevent `compile` from binding in the current namespace When `compile` is used on a top-level definition, do not create a binding in the current namespace, but arrange for a suitable binding to be in place for the target namespace. Closes #1036 --- pkgs/base/info.rkt | 2 +- .../scribblings/raco/zo-struct.scrbl | 25 +- .../tests/racket/modprot.rktl | 1 + .../tests/racket/namespac.rktl | 113 +++-- .../tests/racket/optimize.rktl | 4 +- pkgs/racket-test-core/tests/racket/stx.rktl | 4 +- racket/src/racket/src/compenv.c | 73 ++- racket/src/racket/src/compile.c | 37 +- racket/src/racket/src/cstartup.inc | 431 +++++++++--------- racket/src/racket/src/env.c | 61 ++- racket/src/racket/src/eval.c | 57 ++- racket/src/racket/src/marshal.c | 42 +- racket/src/racket/src/module.c | 8 +- racket/src/racket/src/mzmark_compenv.inc | 6 + racket/src/racket/src/mzmark_type.inc | 4 + racket/src/racket/src/mzmarksrc.c | 5 + racket/src/racket/src/schpriv.h | 11 +- racket/src/racket/src/schvers.h | 4 +- 18 files changed, 569 insertions(+), 319 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 2f61c6306d..3aa51238e1 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.14") +(define version "6.2.900.15") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl index 7cd3875368..bc92d31f64 100644 --- a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl +++ b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl @@ -36,15 +36,28 @@ structures that are produced by @racket[zo-parse] and consumed by @defstruct+[(compilation-top zo) ([max-let-depth exact-nonnegative-integer?] + [binding-namess (hash/c exact-nonnegative-integer? + (hash/c symbol? identifier?))] [prefix prefix?] [code (or/c form? any/c)])]{ - Wraps compiled code. The @racket[max-let-depth] field indicates the + Wraps compiled code. + + The @racket[max-let-depth] field indicates the maximum stack depth that @racket[code] creates (not counting the - @racket[prefix] array). The @racket[prefix] field describes top-level - variables, module-level variables, and quoted syntax-objects accessed - by @racket[code]. The @racket[code] field contains executable code; - it is normally a @racket[form], but a literal value is represented as - itself.} + @racket[prefix] array). + + The @racket[binding-namess] field provides a per-phase mapping from + symbols that appear in @racket[prefix] for top-level + @racket[def-values] forms and in top-level @racket[def-syntaxes] + forms. Each symbol is mapped to an identifier that will be bound + (after introduction into the namespace) by the definition. + + The @racket[prefix] field describes top-level variables, + module-level variables, and quoted syntax-objects accessed by + @racket[code]. + + The @racket[code] field contains executable code; it is normally a + @racket[form], but a literal value is represented as itself.} @defstruct+[(prefix zo) ([num-lifts exact-nonnegative-integer?] diff --git a/pkgs/racket-test-core/tests/racket/modprot.rktl b/pkgs/racket-test-core/tests/racket/modprot.rktl index 1a132cba8b..fa5cfe5655 100644 --- a/pkgs/racket-test-core/tests/racket/modprot.rktl +++ b/pkgs/racket-test-core/tests/racket/modprot.rktl @@ -220,6 +220,7 @@ (zo-marshal (compilation-top 10 + #hash() (prefix 0 (list 'dummy) null diff --git a/pkgs/racket-test-core/tests/racket/namespac.rktl b/pkgs/racket-test-core/tests/racket/namespac.rktl index ce61775ebe..7852725e31 100644 --- a/pkgs/racket-test-core/tests/racket/namespac.rktl +++ b/pkgs/racket-test-core/tests/racket/namespac.rktl @@ -326,47 +326,82 @@ ;; be transferred to another namespace (let () - ;; transfer a `require` - (define c - (parameterize ([current-namespace (make-base-namespace)]) - (compile '(require racket/base)))) - (parameterize ([current-namespace (make-base-empty-namespace)]) - (test (void) 'eval (eval c)) - (test add1 eval 'add1))) + (define (check-namespace-transfer compile-wrap) + (let () + ;; transfer a `require` + (define c + (parameterize ([current-namespace (make-base-namespace)]) + (compile-wrap (compile '(require racket/base))))) + (parameterize ([current-namespace (make-base-empty-namespace)]) + (test (void) 'eval (eval c)) + (test add1 eval 'add1))) -(let () - ;; transfer a definition, reference is visible, original - ;; namespace is unchanged - (define-values (c get) - (parameterize ([current-namespace (make-base-namespace)]) - (define c (compile '(define one 1))) - (values - c - (eval '(lambda () one))))) - (parameterize ([current-namespace (make-base-empty-namespace)]) - (test (void) 'eval (eval c)) - (test 1 eval 'one) - (err/rt-test (get) exn:fail:contract:variable?))) + (let () + ;; transfer a definition, reference is visible, original + ;; namespace is unchanged + (define-values (c get) + (parameterize ([current-namespace (make-base-namespace)]) + (define c (compile-wrap (compile '(define one 1)))) + (values + c + (eval '(lambda () one))))) + (parameterize ([current-namespace (make-base-empty-namespace)]) + (test (void) 'eval (eval c)) + (test 1 eval 'one) + (err/rt-test (get) exn:fail:contract:variable?))) -(let () - ;; transfer a definition of a macro-introduced variable, and - ;; check access via a syntax object that is compiled at the same time: - (define-values (c get) - (parameterize ([current-namespace (make-base-namespace)]) - (eval '(define-syntax-rule (m id) - (begin - (define one 1) - (define id (quote-syntax one)) - one))) - (define c (compile '(m id))) - (values - c - (eval '(lambda () one))))) - (parameterize ([current-namespace (make-base-empty-namespace)]) - (test 1 'eval (eval c)) - (err/rt-test (eval 'one) exn:fail:syntax?) - (test 1 eval (eval 'id)) - (err/rt-test (get) exn:fail:contract:variable?))) + (let () + ;; transfer a definition of a macro-introduced variable, and + ;; check access via a syntax object that is compiled at the same time: + (define-values (c get) + (parameterize ([current-namespace (make-base-namespace)]) + (eval '(define-syntax-rule (m id) + (begin + (define one 1) + (define id (quote-syntax one)) + one))) + (define c (compile-wrap (compile '(m id)))) + (values + c + (eval '(lambda () one))))) + (parameterize ([current-namespace (make-base-empty-namespace)]) + (test 1 'eval (eval c)) + (err/rt-test (eval 'one) exn:fail:syntax?) + (test #t identifier? (eval 'id)) + (test 1 eval (eval 'id)) + (err/rt-test (get) exn:fail:contract:variable?)))) + (check-namespace-transfer values) + (check-namespace-transfer (lambda (c) + (define o (open-output-bytes)) + (write c o) + (parameterize ([read-accept-compiled #t]) + (read (open-input-bytes (get-output-bytes o))))))) + +;; ---------------------------------------- +;; Make sure compilation doesn't bind in the current namespace + +(parameterize ([current-namespace (make-base-namespace)]) + (eval '(define-syntax-rule (m2 c-id r-id) + (begin + (require (rename-in racket/base [+ plus])) + (define (c-id) (compile #'(define plus 1))) + (define (r-id) (eval #'plus))))) + (eval '(m2 def ref)) + (test + eval '(ref)) + (eval '(def)) + (test + eval '(ref)) + (eval (eval '(def))) + (test 1 eval '(ref))) + +#| +(define-syntax-rule (m3 c-id) + (begin + (define-syntax plus #f) + (define (c-id) (compile #'(define plus plus))))) + +(m3 cdef) +(cdef) +|# ;; ---------------------------------------- diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 7c930886e5..765556b6c2 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -4234,8 +4234,8 @@ (write-bytes (zo-marshal (match m - [(compilation-top max-let-depth prefix code) - (compilation-top max-let-depth prefix + [(compilation-top max-let-depth binding-namess prefix code) + (compilation-top max-let-depth binding-namess prefix (let ([body (mod-body code)]) (struct-copy mod code [body (match body diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 474c6d4faf..7a5abe1e3c 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -1282,7 +1282,7 @@ (let-syntax ([z (lambda (stx) #`#,(@@foo 3))]) z)) -(test (void) eval (expand #'(begin-for-syntax (define @@zoo (@@foo 2))))) +(test (void) eval-syntax (expand #'(begin-for-syntax (define @@zoo (@@foo 2))))) (define-syntax (@@x stx) #`#, @@zoo) (test 2 '@@x/@@zoo @@x) (begin-for-syntax (define @@zoo2 (@@foo 2))) @@ -1290,7 +1290,7 @@ (test 2 '@@x/@@zoo @@x) (begin-for-syntax (@@foo 1)) -(test (void) eval (expand #'(begin-for-syntax (@@foo 1)))) +(test (void) eval-syntax (expand #'(begin-for-syntax (@@foo 1)))) (module @@p racket/base (require (for-syntax racket/base diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index d9e1ce51fe..e20cfc60f9 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -1706,7 +1706,7 @@ Scheme_Object *scheme_get_shadower(Scheme_Object *sym, Scheme_Comp_Env *env, int return sym; } -static Scheme_Hash_Table *get_binding_names_table(Scheme_Env *env) +Scheme_Hash_Table *scheme_get_binding_names_table(Scheme_Env *env) { Scheme_Hash_Table *binding_names; @@ -1753,22 +1753,23 @@ static int binding_name_available(Scheme_Hash_Table *binding_names, Scheme_Objec return 0; } -static Scheme_Object *select_binding_name(Scheme_Object *sym, Scheme_Env *env, Scheme_Object *id) +static Scheme_Object *select_binding_name(Scheme_Object *sym, Scheme_Env *env, + Scheme_Object *id, Scheme_Object *orig_id) { int i; char onstack[50], *buf; intptr_t len; Scheme_Hash_Table *binding_names; - binding_names = get_binding_names_table(env); + binding_names = scheme_get_binding_names_table(env); /* Use a plain symbol only if the binding has no extra scopes: */ if (SCHEME_SYM_WEIRDP(sym) - || scheme_stx_equal_module_context(id, ((env->module && env->module->ii_src) - ? env->module->ii_src - : env->stx_context))) { - if (binding_name_available(binding_names, sym, id, scheme_env_phase(env))) { - scheme_hash_set(binding_names, sym, id); + || scheme_stx_equal_module_context(orig_id, ((env->module && env->module->ii_src) + ? env->module->ii_src + : env->stx_context))) { + if (binding_name_available(binding_names, sym, orig_id, scheme_env_phase(env))) { + scheme_hash_set(binding_names, sym, orig_id); return sym; } } @@ -1786,7 +1787,7 @@ static Scheme_Object *select_binding_name(Scheme_Object *sym, Scheme_Env *env, S sym = scheme_intern_exact_parallel_symbol(buf, strlen(buf)); if (binding_name_available(binding_names, sym, id, scheme_env_phase(env))) { - scheme_hash_set(binding_names, sym, id); + scheme_hash_set(binding_names, sym, orig_id); return sym; } @@ -1794,26 +1795,42 @@ static Scheme_Object *select_binding_name(Scheme_Object *sym, Scheme_Env *env, S } } -Scheme_Object *scheme_global_binding(Scheme_Object *id, Scheme_Env *env) +static int binding_matches_env(Scheme_Object *binding, Scheme_Env *env, Scheme_Object *phase) { - Scheme_Object *sym, *binding, *phase; + return (SCHEME_VECTORP(binding) + && SAME_OBJ(SCHEME_VEC_ELS(binding)[0], + (env->module + ? env->module->self_modidx + : scheme_false)) + && SAME_OBJ(SCHEME_VEC_ELS(binding)[2], phase)); +} + +Scheme_Object *scheme_global_binding(Scheme_Object *id, Scheme_Env *env, int for_top_level) +{ + Scheme_Object *sym, *binding, *phase, *orig_id = id; int exact_match; phase = scheme_env_phase(env); + if (for_top_level) { + /* While compiling, we want to avoid binding in the top-level namespace. + Adding an extra scope avoids that while still letting us have some binding + to generate names for top-level definitions. */ + if (!env->tmp_bind_scope) { + sym = scheme_new_scope(SCHEME_STX_MODULE_SCOPE); + env->tmp_bind_scope = sym; + } + id = scheme_stx_add_scope(id, env->tmp_bind_scope, phase); + } + binding = scheme_stx_lookup_stop_at_free_eq(id, phase, &exact_match); if (!SCHEME_FALSEP(binding)) { if (exact_match) { - if (SCHEME_VECTORP(binding) - && SAME_OBJ(SCHEME_VEC_ELS(binding)[0], - (env->module - ? env->module->self_modidx - : scheme_false)) - && SAME_OBJ(SCHEME_VEC_ELS(binding)[2], phase)) { + if (binding_matches_env(binding, env, phase)) { sym = SCHEME_VEC_ELS(binding)[1]; /* Make sure name is in binding_names and with a specific `id`: */ - scheme_hash_set(get_binding_names_table(env), sym, id); + scheme_hash_set(scheme_get_binding_names_table(env), sym, orig_id); return sym; } /* Since the binding didn't match, we'll "shadow" the binding @@ -1821,7 +1838,7 @@ Scheme_Object *scheme_global_binding(Scheme_Object *id, Scheme_Env *env) } } - sym = select_binding_name(SCHEME_STX_VAL(id), env, id); + sym = select_binding_name(SCHEME_STX_VAL(id), env, id, orig_id); scheme_add_module_binding(id, phase, (env->module ? env->module->self_modidx : scheme_false), @@ -1840,8 +1857,24 @@ Scheme_Object *scheme_future_global_binding(Scheme_Object *id, Scheme_Env *env) /* The identifier id is being referenced before it has a binding. We want to allow it, anyway, perhaps because it's outside of a module context or because it's phase-1 code. So, we assume that it's going to - have no extra scopes and get the base name. */ + have no extra scopes and get the base name. + + Then again, if `id` has a binding after adding the environment's temporary + binding scope, then map the identifier to that temporary binding's name. + That special case allows compiling a `define` to create a binding that + can be referenced in the same compilation. */ { + if (env->tmp_bind_scope) { + Scheme_Object *binding, *phase; + + phase = scheme_env_phase(env); + id = scheme_stx_add_scope(id, env->tmp_bind_scope, phase); + binding = scheme_stx_lookup_stop_at_free_eq(id, phase, NULL); + + if (binding_matches_env(binding, env, phase)) + return SCHEME_VEC_ELS(binding)[1]; + } + return SCHEME_STX_VAL(id); } diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 3cf212b65d..5d8105ff1d 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -803,7 +803,7 @@ void scheme_define_parse(Scheme_Object *form, vars = scheme_revert_use_site_scopes(vars, env); - *var = vars; + *var = vars; scheme_begin_dup_symbol_check(&r, env); @@ -822,6 +822,25 @@ void scheme_define_parse(Scheme_Object *form, scheme_wrong_syntax(NULL, *var, form, "bad variable list"); } +static Scheme_Object *global_binding(Scheme_Object *id, Scheme_Comp_Env *env) +{ + Scheme_Object *sym; + + sym = scheme_global_binding(id, env->genv, env->flags & SCHEME_TMP_TL_BIND_FRAME); + + if (env->binding_namess && !SAME_OBJ(sym, SCHEME_STX_VAL(id))) { + /* Record the new binding */ + Scheme_Hash_Tree *binds; + binds = (Scheme_Hash_Tree *)scheme_hash_get(env->binding_namess, scheme_env_phase(env->genv)); + if (!binds) + binds = scheme_make_hash_tree(0); + binds = scheme_hash_tree_set(binds, sym, id); + scheme_hash_set(env->binding_namess, scheme_env_phase(env->genv), (Scheme_Object *)binds); + } + + return sym; +} + static Scheme_Object * defn_targets_syntax (Scheme_Object *var, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec) { @@ -831,7 +850,7 @@ defn_targets_syntax (Scheme_Object *var, Scheme_Comp_Env *env, Scheme_Compile_In Scheme_Object *name, *pr, *bucket; name = SCHEME_STX_CAR(var); - name = scheme_global_binding(name, env->genv); + name = global_binding(name, env); if (rec[drec].resolve_module_ids || !env->genv->module) { bucket = (Scheme_Object *)scheme_global_bucket(name, env->genv); @@ -3410,9 +3429,7 @@ static void prep_exp_env_compile_rec(Scheme_Compile_Info *rec, int drec) static Scheme_Object *stx_val(Scheme_Object *name, Scheme_Object *_env) { - Scheme_Env *env = (Scheme_Env *)_env; - - return scheme_global_binding(name, env); + return global_binding(name, (Scheme_Comp_Env *)_env); } static Scheme_Object * @@ -3434,7 +3451,7 @@ do_define_syntaxes_syntax(Scheme_Object *form, Scheme_Comp_Env *env, scheme_prepare_exp_env(env->genv); scheme_prepare_compile_env(env->genv->exp_env); - names = scheme_named_map_1(NULL, stx_val, names, (Scheme_Object *)env->genv); + names = scheme_named_map_1(NULL, stx_val, names, (Scheme_Object *)env); exp_env = scheme_new_comp_env(env->genv->exp_env, env->insp, NULL, 0); @@ -3517,9 +3534,11 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem scheme_prepare_exp_env(in_env->genv); scheme_prepare_compile_env(in_env->genv->exp_env); - if (rec[drec].comp) - env = scheme_new_comp_env(in_env->genv->exp_env, in_env->insp, NULL, 0); - else + if (rec[drec].comp) { + env = scheme_new_comp_env(in_env->genv->exp_env, in_env->insp, NULL, + (in_env->flags & SCHEME_TMP_TL_BIND_FRAME)); + env->bindings = in_env->bindings; + } else env = scheme_new_expand_env(in_env->genv->exp_env, in_env->insp, NULL, 0); if (rec[drec].comp) diff --git a/racket/src/racket/src/cstartup.inc b/racket/src/racket/src/cstartup.inc index 8e06f64f38..116af35bcd 100644 --- a/racket/src/racket/src/cstartup.inc +++ b/racket/src/racket/src/cstartup.inc @@ -1,12 +1,12 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,53,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,0,1,0,0,8, 0,18,0,22,0,26,0,31,0,38,0,42,0,47,0,59,0,66,0,69,0, 82,0,89,0,94,0,103,0,109,0,123,0,137,0,140,0,146,0,157,0,159, 0,173,0,180,0,202,0,204,0,218,0,246,0,251,0,255,0,72,1,79,1, 90,1,128,1,135,1,144,1,177,1,210,1,16,2,21,2,102,2,107,2,112, 2,133,2,30,3,51,3,104,3,173,3,242,3,132,4,24,5,35,5,118,5, -0,0,147,7,0,0,3,1,5,105,110,115,112,48,71,35,37,109,105,110,45, +0,0,148,7,0,0,3,1,5,105,110,115,112,48,71,35,37,109,105,110,45, 115,116,120,29,11,11,11,65,97,110,100,66,99,111,110,100,68,100,101,102,105, 110,101,65,108,101,116,66,108,101,116,42,73,108,101,116,42,45,118,97,108,117, 101,115,68,108,101,116,114,101,99,64,111,114,74,112,97,114,97,109,101,116,101, @@ -72,37 +72,37 @@ 22,82,248,22,164,4,196,249,22,157,4,80,143,42,39,28,248,22,64,248,22, 158,4,248,22,81,197,250,22,90,2,27,248,22,90,248,22,164,20,199,248,22, 102,198,27,248,22,158,4,248,22,164,20,197,250,22,90,2,27,248,22,90,248, -22,81,197,250,22,91,2,24,248,22,165,20,199,248,22,165,20,202,144,39,20, -121,145,2,1,39,16,1,11,16,0,20,27,15,61,9,2,2,2,2,2,3, -11,11,11,11,9,9,11,11,11,10,39,80,143,39,39,20,121,145,2,1,39, -16,0,16,0,41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4,2, -5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,16,11, -11,11,11,11,11,11,11,11,11,11,11,16,11,2,4,2,5,2,6,2,7, -2,8,2,9,2,10,2,11,2,12,2,13,2,14,39,50,40,16,0,39,16, -1,2,15,40,11,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0, -16,0,16,0,39,39,16,12,16,5,11,20,15,16,2,20,14,144,39,39,40, -80,143,39,39,39,20,121,145,2,1,39,16,1,2,15,16,1,33,36,10,16, -5,2,13,88,148,8,36,40,56,40,9,223,0,33,37,39,20,121,145,2,1, -39,16,1,2,15,16,0,11,16,5,2,14,88,148,8,36,40,56,40,9,223, -0,33,38,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,4, -88,148,8,36,40,56,42,9,223,0,33,39,39,20,121,145,2,1,39,16,1, -2,15,16,1,33,40,11,16,5,2,11,88,148,8,36,40,59,42,9,223,0, -33,41,39,20,121,145,2,1,39,16,1,2,15,16,1,33,42,11,16,5,2, -7,88,148,8,36,40,61,40,9,223,0,33,45,39,20,121,145,2,1,39,16, -1,2,15,16,0,11,16,5,2,10,88,148,8,36,40,56,40,9,223,0,33, -47,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,8,88,148, -8,36,40,57,40,9,223,0,33,48,39,20,121,145,2,1,39,16,1,2,15, -16,0,11,16,5,2,9,88,148,8,36,40,57,40,9,223,0,33,49,39,20, -121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,12,88,148,8,36,40, -59,40,9,223,0,33,50,39,20,121,145,2,1,39,16,1,2,15,16,0,11, -16,5,2,5,88,148,8,36,40,61,42,9,223,0,33,51,39,20,121,145,2, -1,39,16,1,2,15,16,1,33,52,11,16,5,2,6,88,148,8,36,40,57, -40,9,223,0,33,53,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16, -0,94,2,17,2,18,93,2,17,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 2092); +22,81,197,250,22,91,2,24,248,22,165,20,199,248,22,165,20,202,145,39,9, +20,121,145,2,1,39,16,1,11,16,0,20,27,15,61,9,2,2,2,2,2, +3,11,11,11,11,9,9,11,11,11,10,39,80,143,39,39,20,121,145,2,1, +39,16,0,16,0,41,42,39,16,0,39,16,0,39,11,11,11,16,11,2,4, +2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,16, +11,11,11,11,11,11,11,11,11,11,11,11,16,11,2,4,2,5,2,6,2, +7,2,8,2,9,2,10,2,11,2,12,2,13,2,14,39,50,40,16,0,39, +16,1,2,15,40,11,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16, +0,16,0,16,0,39,39,16,12,16,5,11,20,15,16,2,20,14,144,39,39, +40,80,143,39,39,39,20,121,145,2,1,39,16,1,2,15,16,1,33,36,10, +16,5,2,13,88,148,8,36,40,56,40,9,223,0,33,37,39,20,121,145,2, +1,39,16,1,2,15,16,0,11,16,5,2,14,88,148,8,36,40,56,40,9, +223,0,33,38,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2, +4,88,148,8,36,40,56,42,9,223,0,33,39,39,20,121,145,2,1,39,16, +1,2,15,16,1,33,40,11,16,5,2,11,88,148,8,36,40,59,42,9,223, +0,33,41,39,20,121,145,2,1,39,16,1,2,15,16,1,33,42,11,16,5, +2,7,88,148,8,36,40,61,40,9,223,0,33,45,39,20,121,145,2,1,39, +16,1,2,15,16,0,11,16,5,2,10,88,148,8,36,40,56,40,9,223,0, +33,47,39,20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,8,88, +148,8,36,40,57,40,9,223,0,33,48,39,20,121,145,2,1,39,16,1,2, +15,16,0,11,16,5,2,9,88,148,8,36,40,57,40,9,223,0,33,49,39, +20,121,145,2,1,39,16,1,2,15,16,0,11,16,5,2,12,88,148,8,36, +40,59,40,9,223,0,33,50,39,20,121,145,2,1,39,16,1,2,15,16,0, +11,16,5,2,5,88,148,8,36,40,61,42,9,223,0,33,51,39,20,121,145, +2,1,39,16,1,2,15,16,1,33,52,11,16,5,2,6,88,148,8,36,40, +57,40,9,223,0,33,53,39,20,121,145,2,1,39,16,1,2,15,16,0,11, +16,0,94,2,17,2,18,93,2,17,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 2093); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,53,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,1,0,0,8, 0,16,0,29,0,34,0,51,0,63,0,85,0,114,0,158,0,164,0,178,0, 193,0,211,0,223,0,239,0,253,0,19,1,39,1,73,1,90,1,107,1,130, @@ -122,7 +122,7 @@ 109,45,167,45,200,45,76,46,235,46,251,46,92,47,109,47,187,49,238,51,254, 51,228,53,160,54,162,54,189,54,205,54,221,54,62,55,129,56,61,57,77,57, 86,57,93,57,159,58,225,59,87,60,133,63,7,64,139,64,84,66,34,67,76, -67,184,67,0,0,131,75,0,0,3,1,5,105,110,115,112,48,69,35,37,117, +67,184,67,0,0,132,75,0,0,3,1,5,105,110,115,112,48,69,35,37,117, 116,105,108,115,74,112,97,116,104,45,115,116,114,105,110,103,63,66,98,115,98, 115,78,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116,104,73,114,101, 114,111,111,116,45,112,97,116,104,1,20,102,105,110,100,45,101,120,101,99,117, @@ -947,109 +947,110 @@ 27,250,80,144,45,43,42,248,22,152,16,2,56,11,11,27,248,22,139,4,23, 199,1,27,28,23,194,2,23,194,1,86,94,23,194,1,39,27,248,22,139,4, 23,202,1,249,22,140,6,23,198,1,20,20,95,88,148,8,36,39,51,11,9, -224,3,2,33,190,2,23,195,1,23,196,1,248,80,144,41,8,54,42,193,144, -39,20,121,145,2,1,39,16,1,11,16,0,20,27,15,56,9,2,2,2,2, -29,11,11,11,11,11,11,11,9,9,11,11,11,10,46,80,143,39,39,20,121, -145,2,1,54,16,40,2,3,2,4,2,5,2,6,2,7,2,8,2,9,30, -2,11,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,45, -107,101,121,11,6,30,2,11,1,23,101,120,116,101,110,100,45,112,97,114,97, -109,101,116,101,114,105,122,97,116,105,111,110,11,4,2,12,2,13,2,14,2, -15,2,16,2,17,2,18,30,2,11,1,19,99,97,99,104,101,45,99,111,110, -102,105,103,117,114,97,116,105,111,110,11,1,2,19,2,20,2,21,2,22,2, -23,2,24,2,25,2,26,2,27,2,28,2,29,30,2,11,1,21,101,120,99, -101,112,116,105,111,110,45,104,97,110,100,108,101,114,45,107,101,121,11,3,2, -30,2,31,2,32,2,33,2,34,2,35,2,36,2,37,2,38,2,39,2,40, -16,0,40,42,39,16,0,39,16,19,2,13,2,14,2,12,2,25,2,4,2, -35,2,23,2,24,2,19,2,29,2,33,2,21,2,22,2,31,2,27,2,30, -2,32,2,36,2,28,58,11,11,11,16,17,2,9,2,17,2,15,2,40,2, -16,2,7,2,26,2,39,2,18,2,20,2,38,2,5,2,34,2,8,2,37, -2,3,2,6,16,17,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, -11,11,16,17,2,9,2,17,2,15,2,40,2,16,2,7,2,26,2,39,2, -18,2,20,2,38,2,5,2,34,2,8,2,37,2,3,2,6,56,56,40,12, -11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39, -39,16,51,20,15,16,2,32,0,88,148,8,36,40,48,11,2,3,222,33,78, -80,144,39,39,40,20,15,16,2,249,22,155,7,7,92,7,92,80,144,39,40, -40,20,15,16,2,88,148,8,36,40,57,41,2,5,223,0,33,83,80,144,39, -41,40,20,15,16,2,88,148,8,36,41,61,41,2,6,223,0,33,85,80,144, -39,42,40,20,15,16,2,20,26,96,2,7,88,148,8,36,42,8,24,8,32, -9,223,0,33,92,88,148,8,36,41,50,55,9,223,0,33,93,88,148,8,36, -40,49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22,164, -16,248,22,167,8,27,28,249,22,169,9,247,22,180,8,2,43,6,1,1,59, -6,1,1,58,250,22,137,8,6,14,14,40,91,94,126,97,93,42,41,126,97, -40,46,42,41,23,196,2,23,196,1,88,148,8,36,41,51,11,2,8,223,0, -33,98,80,144,39,44,40,20,15,16,2,88,148,39,40,8,38,8,128,6,2, -9,223,0,33,99,80,144,39,45,40,20,15,16,2,32,0,88,148,8,36,41, -50,11,2,12,222,33,100,80,144,39,48,40,20,15,16,2,32,0,88,148,8, -36,42,51,11,2,13,222,33,102,80,144,39,49,40,20,15,16,2,32,0,88, -148,8,36,41,49,11,2,14,222,33,103,80,144,39,50,40,20,15,16,2,88, -148,39,42,53,8,128,128,2,15,223,0,33,105,80,144,39,51,40,20,15,16, -2,88,148,39,44,55,8,128,128,2,17,223,0,33,107,80,144,39,53,40,20, -15,16,2,88,148,39,39,56,55,9,223,0,33,108,80,144,39,8,40,42,20, -15,16,2,88,148,39,39,47,16,4,39,40,8,128,4,39,2,18,223,0,33, -109,80,144,39,54,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,110, -80,144,39,8,41,42,20,15,16,2,88,148,39,39,47,16,4,39,40,8,128, -8,39,2,20,223,0,33,111,80,144,39,57,40,20,15,16,2,88,148,8,36, -39,8,38,8,128,6,9,223,0,33,112,80,144,39,8,42,42,20,15,16,2, -88,148,8,36,40,50,16,4,39,39,8,128,16,39,2,21,223,0,33,113,80, -144,39,58,40,20,15,16,2,20,28,143,32,0,88,148,39,40,48,11,2,22, -222,33,114,32,0,88,148,39,40,48,11,2,22,222,33,115,80,144,39,59,40, -20,15,16,2,88,148,8,36,40,50,8,240,0,128,0,0,2,23,223,0,33, -116,80,144,39,60,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33,117, -80,144,39,8,43,42,20,15,16,2,88,148,8,36,40,51,16,4,39,40,8, -128,32,39,2,24,223,0,33,118,80,144,39,61,40,20,15,16,2,88,148,39, -40,56,55,2,19,223,0,33,119,80,144,39,56,40,20,15,16,2,88,148,8, -36,41,58,16,4,8,240,0,128,0,0,8,32,8,128,64,39,2,50,223,0, -33,120,80,144,39,8,44,42,20,15,16,2,88,148,8,36,42,52,16,4,39, -39,8,128,64,39,2,25,223,0,33,121,80,144,39,8,23,40,20,15,16,2, -88,148,39,39,56,55,9,223,0,33,122,80,144,39,8,45,42,20,15,16,2, -88,148,8,36,39,57,16,4,8,240,0,128,0,0,8,137,2,8,128,128,39, -2,26,223,0,33,123,80,144,39,8,24,40,20,15,16,2,247,22,140,2,80, -144,39,8,25,40,20,15,16,2,248,22,16,67,115,116,97,109,112,80,144,39, -8,26,40,20,15,16,2,88,148,39,40,49,8,240,0,0,0,4,9,223,0, -33,125,80,144,39,8,46,42,20,15,16,2,88,148,39,41,51,16,4,39,8, -128,80,8,240,0,64,0,0,39,2,29,223,0,33,133,2,80,144,39,8,27, -40,20,15,16,2,32,0,88,148,8,36,40,48,11,2,30,222,33,134,2,80, -144,39,8,29,40,20,15,16,2,88,148,8,36,42,48,8,240,0,0,0,2, -74,109,97,107,101,45,104,97,110,100,108,101,114,223,0,33,136,2,80,144,39, -8,47,42,20,15,16,2,88,148,39,40,47,16,4,8,128,6,8,128,104,8, -240,0,128,0,0,39,2,31,223,0,33,146,2,80,144,39,8,30,40,20,15, -16,2,88,148,39,41,59,16,2,39,8,240,0,128,0,0,2,32,223,0,33, -148,2,80,144,39,8,31,40,20,15,16,2,88,148,8,36,41,61,16,4,39, -8,240,0,64,0,0,39,40,2,50,223,0,33,149,2,80,144,39,8,48,42, -20,15,16,2,88,148,39,47,8,33,16,4,39,39,40,41,67,99,108,111,111, -112,223,0,33,156,2,80,144,39,8,49,42,20,15,16,2,88,148,39,44,8, -25,16,4,39,8,240,0,192,0,0,39,42,2,16,223,0,33,157,2,80,144, -39,52,40,20,15,16,2,88,148,39,42,58,16,4,47,39,43,39,2,33,223, -0,33,162,2,80,144,39,8,32,40,20,15,16,2,32,0,88,148,39,42,53, -11,2,35,222,33,163,2,80,144,39,8,34,40,20,15,16,2,32,0,88,148, -8,36,44,8,27,11,2,36,222,33,168,2,80,144,39,8,35,40,20,15,16, -2,20,28,143,32,0,88,148,8,36,41,55,11,2,37,222,33,171,2,88,148, -8,100,41,52,16,4,39,39,47,39,2,37,223,0,33,173,2,80,144,39,8, -36,40,20,15,16,2,20,28,143,32,0,88,148,8,36,41,55,11,2,34,222, -33,178,2,88,148,8,100,41,52,16,4,39,39,47,39,2,34,223,0,33,179, -2,80,144,39,8,33,40,20,15,16,2,20,28,143,32,0,88,148,39,40,47, -11,2,38,222,33,180,2,32,0,88,148,39,40,47,11,2,38,222,33,181,2, -80,144,39,8,37,40,20,15,16,2,88,148,8,36,40,58,16,4,55,41,39, -43,2,50,223,0,33,182,2,80,144,39,8,50,42,20,15,16,2,88,148,8, -36,40,58,16,4,55,41,39,47,2,50,223,0,33,183,2,80,144,39,8,51, -42,20,15,16,2,88,148,39,39,56,55,9,223,0,33,184,2,80,144,39,8, -52,42,20,15,16,2,88,148,8,36,40,8,23,16,4,55,41,39,8,32,2, -50,223,0,33,185,2,80,144,39,8,53,42,20,15,16,2,20,26,96,2,39, -88,148,39,39,60,16,4,8,32,8,140,2,39,43,9,223,0,33,186,2,88, -148,39,40,61,16,4,8,32,8,140,2,39,47,9,223,0,33,187,2,88,148, -39,41,8,30,16,4,8,48,8,139,2,39,8,48,9,223,0,33,188,2,80, -144,39,8,38,40,20,15,16,2,88,148,8,36,40,60,16,4,8,128,6,39, -39,8,64,2,50,223,0,33,189,2,80,144,39,8,54,42,20,15,16,2,88, -148,8,36,42,56,16,4,55,39,39,8,64,2,40,223,0,33,191,2,80,144, -39,8,39,40,95,29,94,2,10,70,35,37,107,101,114,110,101,108,11,29,94, -2,10,71,35,37,109,105,110,45,115,116,120,11,2,11,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 19760); +224,3,2,33,190,2,23,195,1,23,196,1,248,80,144,41,8,54,42,193,145, +39,9,20,121,145,2,1,39,16,1,11,16,0,20,27,15,56,9,2,2,2, +2,29,11,11,11,11,11,11,11,9,9,11,11,11,10,46,80,143,39,39,20, +121,145,2,1,54,16,40,2,3,2,4,2,5,2,6,2,7,2,8,2,9, +30,2,11,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110, +45,107,101,121,11,6,30,2,11,1,23,101,120,116,101,110,100,45,112,97,114, +97,109,101,116,101,114,105,122,97,116,105,111,110,11,4,2,12,2,13,2,14, +2,15,2,16,2,17,2,18,30,2,11,1,19,99,97,99,104,101,45,99,111, +110,102,105,103,117,114,97,116,105,111,110,11,1,2,19,2,20,2,21,2,22, +2,23,2,24,2,25,2,26,2,27,2,28,2,29,30,2,11,1,21,101,120, +99,101,112,116,105,111,110,45,104,97,110,100,108,101,114,45,107,101,121,11,3, +2,30,2,31,2,32,2,33,2,34,2,35,2,36,2,37,2,38,2,39,2, +40,16,0,40,42,39,16,0,39,16,19,2,13,2,14,2,12,2,25,2,4, +2,35,2,23,2,24,2,19,2,29,2,33,2,21,2,22,2,31,2,27,2, +30,2,32,2,36,2,28,58,11,11,11,16,17,2,9,2,17,2,15,2,40, +2,16,2,7,2,26,2,39,2,18,2,20,2,38,2,5,2,34,2,8,2, +37,2,3,2,6,16,17,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +11,11,11,16,17,2,9,2,17,2,15,2,40,2,16,2,7,2,26,2,39, +2,18,2,20,2,38,2,5,2,34,2,8,2,37,2,3,2,6,56,56,40, +12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0, +39,39,16,51,20,15,16,2,32,0,88,148,8,36,40,48,11,2,3,222,33, +78,80,144,39,39,40,20,15,16,2,249,22,155,7,7,92,7,92,80,144,39, +40,40,20,15,16,2,88,148,8,36,40,57,41,2,5,223,0,33,83,80,144, +39,41,40,20,15,16,2,88,148,8,36,41,61,41,2,6,223,0,33,85,80, +144,39,42,40,20,15,16,2,20,26,96,2,7,88,148,8,36,42,8,24,8, +32,9,223,0,33,92,88,148,8,36,41,50,55,9,223,0,33,93,88,148,8, +36,40,49,55,9,223,0,33,94,80,144,39,43,40,20,15,16,2,27,248,22, +164,16,248,22,167,8,27,28,249,22,169,9,247,22,180,8,2,43,6,1,1, +59,6,1,1,58,250,22,137,8,6,14,14,40,91,94,126,97,93,42,41,126, +97,40,46,42,41,23,196,2,23,196,1,88,148,8,36,41,51,11,2,8,223, +0,33,98,80,144,39,44,40,20,15,16,2,88,148,39,40,8,38,8,128,6, +2,9,223,0,33,99,80,144,39,45,40,20,15,16,2,32,0,88,148,8,36, +41,50,11,2,12,222,33,100,80,144,39,48,40,20,15,16,2,32,0,88,148, +8,36,42,51,11,2,13,222,33,102,80,144,39,49,40,20,15,16,2,32,0, +88,148,8,36,41,49,11,2,14,222,33,103,80,144,39,50,40,20,15,16,2, +88,148,39,42,53,8,128,128,2,15,223,0,33,105,80,144,39,51,40,20,15, +16,2,88,148,39,44,55,8,128,128,2,17,223,0,33,107,80,144,39,53,40, +20,15,16,2,88,148,39,39,56,55,9,223,0,33,108,80,144,39,8,40,42, +20,15,16,2,88,148,39,39,47,16,4,39,40,8,128,4,39,2,18,223,0, +33,109,80,144,39,54,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33, +110,80,144,39,8,41,42,20,15,16,2,88,148,39,39,47,16,4,39,40,8, +128,8,39,2,20,223,0,33,111,80,144,39,57,40,20,15,16,2,88,148,8, +36,39,8,38,8,128,6,9,223,0,33,112,80,144,39,8,42,42,20,15,16, +2,88,148,8,36,40,50,16,4,39,39,8,128,16,39,2,21,223,0,33,113, +80,144,39,58,40,20,15,16,2,20,28,143,32,0,88,148,39,40,48,11,2, +22,222,33,114,32,0,88,148,39,40,48,11,2,22,222,33,115,80,144,39,59, +40,20,15,16,2,88,148,8,36,40,50,8,240,0,128,0,0,2,23,223,0, +33,116,80,144,39,60,40,20,15,16,2,88,148,39,39,56,55,9,223,0,33, +117,80,144,39,8,43,42,20,15,16,2,88,148,8,36,40,51,16,4,39,40, +8,128,32,39,2,24,223,0,33,118,80,144,39,61,40,20,15,16,2,88,148, +39,40,56,55,2,19,223,0,33,119,80,144,39,56,40,20,15,16,2,88,148, +8,36,41,58,16,4,8,240,0,128,0,0,8,32,8,128,64,39,2,50,223, +0,33,120,80,144,39,8,44,42,20,15,16,2,88,148,8,36,42,52,16,4, +39,39,8,128,64,39,2,25,223,0,33,121,80,144,39,8,23,40,20,15,16, +2,88,148,39,39,56,55,9,223,0,33,122,80,144,39,8,45,42,20,15,16, +2,88,148,8,36,39,57,16,4,8,240,0,128,0,0,8,137,2,8,128,128, +39,2,26,223,0,33,123,80,144,39,8,24,40,20,15,16,2,247,22,140,2, +80,144,39,8,25,40,20,15,16,2,248,22,16,67,115,116,97,109,112,80,144, +39,8,26,40,20,15,16,2,88,148,39,40,49,8,240,0,0,0,4,9,223, +0,33,125,80,144,39,8,46,42,20,15,16,2,88,148,39,41,51,16,4,39, +8,128,80,8,240,0,64,0,0,39,2,29,223,0,33,133,2,80,144,39,8, +27,40,20,15,16,2,32,0,88,148,8,36,40,48,11,2,30,222,33,134,2, +80,144,39,8,29,40,20,15,16,2,88,148,8,36,42,48,8,240,0,0,0, +2,74,109,97,107,101,45,104,97,110,100,108,101,114,223,0,33,136,2,80,144, +39,8,47,42,20,15,16,2,88,148,39,40,47,16,4,8,128,6,8,128,104, +8,240,0,128,0,0,39,2,31,223,0,33,146,2,80,144,39,8,30,40,20, +15,16,2,88,148,39,41,59,16,2,39,8,240,0,128,0,0,2,32,223,0, +33,148,2,80,144,39,8,31,40,20,15,16,2,88,148,8,36,41,61,16,4, +39,8,240,0,64,0,0,39,40,2,50,223,0,33,149,2,80,144,39,8,48, +42,20,15,16,2,88,148,39,47,8,33,16,4,39,39,40,41,67,99,108,111, +111,112,223,0,33,156,2,80,144,39,8,49,42,20,15,16,2,88,148,39,44, +8,25,16,4,39,8,240,0,192,0,0,39,42,2,16,223,0,33,157,2,80, +144,39,52,40,20,15,16,2,88,148,39,42,58,16,4,47,39,43,39,2,33, +223,0,33,162,2,80,144,39,8,32,40,20,15,16,2,32,0,88,148,39,42, +53,11,2,35,222,33,163,2,80,144,39,8,34,40,20,15,16,2,32,0,88, +148,8,36,44,8,27,11,2,36,222,33,168,2,80,144,39,8,35,40,20,15, +16,2,20,28,143,32,0,88,148,8,36,41,55,11,2,37,222,33,171,2,88, +148,8,100,41,52,16,4,39,39,47,39,2,37,223,0,33,173,2,80,144,39, +8,36,40,20,15,16,2,20,28,143,32,0,88,148,8,36,41,55,11,2,34, +222,33,178,2,88,148,8,100,41,52,16,4,39,39,47,39,2,34,223,0,33, +179,2,80,144,39,8,33,40,20,15,16,2,20,28,143,32,0,88,148,39,40, +47,11,2,38,222,33,180,2,32,0,88,148,39,40,47,11,2,38,222,33,181, +2,80,144,39,8,37,40,20,15,16,2,88,148,8,36,40,58,16,4,55,41, +39,43,2,50,223,0,33,182,2,80,144,39,8,50,42,20,15,16,2,88,148, +8,36,40,58,16,4,55,41,39,47,2,50,223,0,33,183,2,80,144,39,8, +51,42,20,15,16,2,88,148,39,39,56,55,9,223,0,33,184,2,80,144,39, +8,52,42,20,15,16,2,88,148,8,36,40,8,23,16,4,55,41,39,8,32, +2,50,223,0,33,185,2,80,144,39,8,53,42,20,15,16,2,20,26,96,2, +39,88,148,39,39,60,16,4,8,32,8,140,2,39,43,9,223,0,33,186,2, +88,148,39,40,61,16,4,8,32,8,140,2,39,47,9,223,0,33,187,2,88, +148,39,41,8,30,16,4,8,48,8,139,2,39,8,48,9,223,0,33,188,2, +80,144,39,8,38,40,20,15,16,2,88,148,8,36,40,60,16,4,8,128,6, +39,39,8,64,2,50,223,0,33,189,2,80,144,39,8,54,42,20,15,16,2, +88,148,8,36,42,56,16,4,55,39,39,8,64,2,40,223,0,33,191,2,80, +144,39,8,39,40,95,29,94,2,10,70,35,37,107,101,114,110,101,108,11,29, +94,2,10,71,35,37,109,105,110,45,115,116,120,11,2,11,9,9,9,39,9, +0}; + EVAL_ONE_SIZED_STR((char *)expr, 19761); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,53,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,8, 0,23,0,48,0,65,0,83,0,105,0,128,0,149,0,171,0,180,0,189,0, -196,0,205,0,212,0,0,0,247,1,0,0,3,1,5,105,110,115,112,48,76, +196,0,205,0,212,0,0,0,248,1,0,0,3,1,5,105,110,115,112,48,76, 35,37,112,108,97,99,101,45,115,116,114,117,99,116,1,23,115,116,114,117,99, 116,58,84,72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,78,84,72, 45,112,108,97,99,101,45,99,104,97,110,110,101,108,79,84,72,45,112,108,97, @@ -1059,25 +1060,25 @@ 97,99,101,45,99,104,97,110,110,101,108,45,105,110,1,20,84,72,45,112,108, 97,99,101,45,99,104,97,110,110,101,108,45,111,117,116,249,80,143,41,42,23, 196,1,39,249,80,143,41,42,23,196,1,39,249,80,143,41,42,195,39,249,80, -143,41,42,23,196,1,40,249,80,143,41,42,195,40,144,39,20,121,145,2,1, -39,16,1,11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11, -11,11,9,9,11,11,11,10,48,80,143,39,39,20,121,145,2,1,39,16,7, -2,3,2,4,2,5,2,6,2,7,2,8,2,9,16,0,40,42,39,16,0, -39,16,2,2,6,2,7,41,11,11,11,16,5,2,4,2,8,2,9,2,5, -2,3,16,5,11,11,11,11,11,16,5,2,4,2,8,2,9,2,5,2,3, -44,44,40,12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0,16, -0,16,0,39,39,16,3,20,15,16,6,253,22,190,10,2,4,11,41,39,11, -248,22,90,249,22,80,22,175,10,88,148,39,40,48,47,9,223,9,33,10,80, -144,39,39,40,80,144,39,40,40,80,144,39,41,40,80,144,39,42,40,80,144, -39,43,40,20,15,16,2,20,28,143,88,148,39,40,48,47,9,223,0,33,11, -88,148,39,40,48,47,9,223,0,33,12,80,144,39,44,40,20,15,16,2,20, -28,143,88,148,39,40,48,47,9,223,0,33,13,88,148,39,40,48,47,9,223, -0,33,14,80,144,39,45,40,93,29,94,67,113,117,111,116,101,70,35,37,107, -101,114,110,101,108,11,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 578); +143,41,42,23,196,1,40,249,80,143,41,42,195,40,145,39,9,20,121,145,2, +1,39,16,1,11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11, +11,11,11,9,9,11,11,11,10,48,80,143,39,39,20,121,145,2,1,39,16, +7,2,3,2,4,2,5,2,6,2,7,2,8,2,9,16,0,40,42,39,16, +0,39,16,2,2,6,2,7,41,11,11,11,16,5,2,4,2,8,2,9,2, +5,2,3,16,5,11,11,11,11,11,16,5,2,4,2,8,2,9,2,5,2, +3,44,44,40,12,11,11,16,0,16,0,16,0,39,39,11,12,11,11,16,0, +16,0,16,0,39,39,16,3,20,15,16,6,253,22,190,10,2,4,11,41,39, +11,248,22,90,249,22,80,22,175,10,88,148,39,40,48,47,9,223,9,33,10, +80,144,39,39,40,80,144,39,40,40,80,144,39,41,40,80,144,39,42,40,80, +144,39,43,40,20,15,16,2,20,28,143,88,148,39,40,48,47,9,223,0,33, +11,88,148,39,40,48,47,9,223,0,33,12,80,144,39,44,40,20,15,16,2, +20,28,143,88,148,39,40,48,47,9,223,0,33,13,88,148,39,40,48,47,9, +223,0,33,14,80,144,39,45,40,93,29,94,67,113,117,111,116,101,70,35,37, +107,101,114,110,101,108,11,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 579); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,53,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,1,0,0,8, 0,15,0,26,0,53,0,59,0,73,0,86,0,112,0,129,0,151,0,159,0, 171,0,186,0,202,0,220,0,241,0,253,0,13,1,36,1,60,1,72,1,103, @@ -1088,7 +1089,7 @@ 13,165,13,160,14,40,15,115,15,22,16,35,16,188,16,116,17,159,17,241,17, 113,18,174,18,182,18,193,18,227,19,74,20,102,20,115,20,36,21,43,21,203, 21,223,21,67,22,89,22,99,22,113,22,151,22,250,22,254,22,5,23,211,23, -104,32,157,32,181,32,205,32,0,0,253,36,0,0,3,1,5,105,110,115,112, +104,32,157,32,181,32,205,32,0,0,254,36,0,0,3,1,5,105,110,115,112, 48,68,35,37,98,111,111,116,72,100,108,108,45,115,117,102,102,105,120,1,25, 100,101,102,97,117,108,116,45,108,111,97,100,47,117,115,101,45,99,111,109,112, 105,108,101,100,67,113,117,111,116,101,29,94,2,5,70,35,37,112,97,114,97, @@ -1488,65 +1489,65 @@ 22,190,4,80,144,40,60,41,248,22,176,5,80,144,40,40,42,248,22,144,15, 80,144,40,48,42,20,18,144,11,80,143,39,59,248,80,144,40,8,27,40,249, 22,31,11,80,144,42,41,40,20,18,144,11,80,143,39,59,248,80,144,40,8, -27,40,249,22,31,11,80,144,42,41,40,144,39,20,121,145,2,1,39,16,1, -11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9, -9,11,11,11,10,41,80,143,39,39,20,121,145,2,1,44,16,28,2,3,2, -4,30,2,6,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111, -110,45,107,101,121,11,6,30,2,6,1,23,101,120,116,101,110,100,45,112,97, -114,97,109,101,116,101,114,105,122,97,116,105,111,110,11,4,30,2,7,74,112, -97,116,104,45,115,116,114,105,110,103,63,42,196,15,2,8,30,2,7,73,114, -101,114,111,111,116,45,112,97,116,104,44,196,16,30,2,7,77,112,97,116,104, -45,97,100,100,45,115,117,102,102,105,120,44,196,12,2,9,2,10,2,11,2, -12,2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22, -30,2,7,1,19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102, -102,105,120,44,196,14,30,2,7,75,102,105,110,100,45,99,111,108,45,102,105, -108,101,49,196,4,30,2,7,78,110,111,114,109,97,108,45,99,97,115,101,45, -112,97,116,104,42,196,11,2,23,2,24,30,2,6,76,114,101,112,97,114,97, -109,101,116,101,114,105,122,101,11,7,16,0,40,42,39,16,0,39,16,16,2, -15,2,16,2,8,2,12,2,17,2,18,2,11,2,4,2,10,2,3,2,20, -2,13,2,14,2,9,2,19,2,22,55,11,11,11,16,3,2,23,2,21,2, -24,16,3,11,11,11,16,3,2,23,2,21,2,24,42,42,40,12,11,11,16, -0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,24, -20,15,16,2,248,22,180,8,71,115,111,45,115,117,102,102,105,120,80,144,39, -39,40,20,15,16,2,88,148,39,41,8,39,8,189,3,2,4,223,0,33,50, -80,144,39,40,40,20,15,16,2,32,0,88,148,8,36,44,55,11,2,9,222, -33,51,80,144,39,47,40,20,15,16,2,20,28,143,32,0,88,148,8,36,40, -45,11,2,10,222,192,32,0,88,148,8,36,40,45,11,2,10,222,192,80,144, -39,48,40,20,15,16,2,247,22,141,2,80,144,39,44,40,20,15,16,2,8, -128,8,80,144,39,49,40,20,15,16,2,249,22,185,8,8,128,8,11,80,144, -39,50,40,20,15,16,2,88,148,8,36,40,53,8,128,32,2,13,223,0,33, -52,80,144,39,51,40,20,15,16,2,88,148,8,36,41,57,8,128,32,2,14, -223,0,33,53,80,144,39,52,40,20,15,16,2,247,22,76,80,144,39,53,40, -20,15,16,2,248,22,16,76,109,111,100,117,108,101,45,108,111,97,100,105,110, -103,80,144,39,54,40,20,15,16,2,11,80,143,39,55,20,15,16,2,11,80, -143,39,56,20,15,16,2,32,0,88,148,39,41,60,11,2,19,222,33,72,80, -144,39,57,40,20,15,16,2,32,0,88,148,8,36,40,52,11,2,20,222,33, -73,80,144,39,58,40,20,15,16,2,11,80,143,39,59,20,15,16,2,88,149, -8,34,40,48,8,240,4,0,16,0,1,21,112,114,101,112,45,112,108,97,110, -101,116,45,114,101,115,111,108,118,101,114,33,40,224,1,0,33,74,80,144,39, -8,28,42,20,15,16,2,88,148,39,40,53,8,240,0,0,3,0,69,103,101, -116,45,100,105,114,223,0,33,75,80,144,39,8,29,42,20,15,16,2,88,148, -39,40,52,8,240,0,0,64,0,74,112,97,116,104,45,115,115,45,62,114,107, -116,223,0,33,76,80,144,39,8,30,42,20,15,16,2,88,148,8,36,40,48, -8,240,0,0,4,0,9,223,0,33,77,80,144,39,8,31,42,20,15,16,2, -88,148,39,40,48,8,240,0,128,0,0,9,223,0,33,78,80,144,39,8,32, -42,20,15,16,2,27,11,20,19,143,39,90,144,40,10,89,146,40,39,10,20, -26,96,2,22,88,148,8,36,41,57,8,32,9,224,2,1,33,79,88,148,39, -42,52,11,9,223,0,33,80,88,148,39,43,8,32,16,4,8,240,44,240,0, -0,8,240,220,241,0,0,40,39,9,224,2,1,33,96,207,80,144,39,60,40, -20,15,16,2,88,148,39,39,48,16,2,8,134,8,8,176,32,2,23,223,0, -33,97,80,144,39,8,25,40,20,15,16,2,20,28,143,88,148,8,36,39,48, -16,2,43,8,144,32,2,24,223,0,33,98,88,148,8,36,39,48,16,2,43, -8,144,32,2,24,223,0,33,99,80,144,39,8,26,40,96,29,94,2,5,70, -35,37,107,101,114,110,101,108,11,29,94,2,5,71,35,37,109,105,110,45,115, -116,120,11,2,7,2,6,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 9714); +27,40,249,22,31,11,80,144,42,41,40,145,39,9,20,121,145,2,1,39,16, +1,11,16,0,20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11, +9,9,11,11,11,10,41,80,143,39,39,20,121,145,2,1,44,16,28,2,3, +2,4,30,2,6,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105, +111,110,45,107,101,121,11,6,30,2,6,1,23,101,120,116,101,110,100,45,112, +97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,11,4,30,2,7,74, +112,97,116,104,45,115,116,114,105,110,103,63,42,196,15,2,8,30,2,7,73, +114,101,114,111,111,116,45,112,97,116,104,44,196,16,30,2,7,77,112,97,116, +104,45,97,100,100,45,115,117,102,102,105,120,44,196,12,2,9,2,10,2,11, +2,12,2,13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,2, +22,30,2,7,1,19,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117, +102,102,105,120,44,196,14,30,2,7,75,102,105,110,100,45,99,111,108,45,102, +105,108,101,49,196,4,30,2,7,78,110,111,114,109,97,108,45,99,97,115,101, +45,112,97,116,104,42,196,11,2,23,2,24,30,2,6,76,114,101,112,97,114, +97,109,101,116,101,114,105,122,101,11,7,16,0,40,42,39,16,0,39,16,16, +2,15,2,16,2,8,2,12,2,17,2,18,2,11,2,4,2,10,2,3,2, +20,2,13,2,14,2,9,2,19,2,22,55,11,11,11,16,3,2,23,2,21, +2,24,16,3,11,11,11,16,3,2,23,2,21,2,24,42,42,40,12,11,11, +16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16, +24,20,15,16,2,248,22,180,8,71,115,111,45,115,117,102,102,105,120,80,144, +39,39,40,20,15,16,2,88,148,39,41,8,39,8,189,3,2,4,223,0,33, +50,80,144,39,40,40,20,15,16,2,32,0,88,148,8,36,44,55,11,2,9, +222,33,51,80,144,39,47,40,20,15,16,2,20,28,143,32,0,88,148,8,36, +40,45,11,2,10,222,192,32,0,88,148,8,36,40,45,11,2,10,222,192,80, +144,39,48,40,20,15,16,2,247,22,141,2,80,144,39,44,40,20,15,16,2, +8,128,8,80,144,39,49,40,20,15,16,2,249,22,185,8,8,128,8,11,80, +144,39,50,40,20,15,16,2,88,148,8,36,40,53,8,128,32,2,13,223,0, +33,52,80,144,39,51,40,20,15,16,2,88,148,8,36,41,57,8,128,32,2, +14,223,0,33,53,80,144,39,52,40,20,15,16,2,247,22,76,80,144,39,53, +40,20,15,16,2,248,22,16,76,109,111,100,117,108,101,45,108,111,97,100,105, +110,103,80,144,39,54,40,20,15,16,2,11,80,143,39,55,20,15,16,2,11, +80,143,39,56,20,15,16,2,32,0,88,148,39,41,60,11,2,19,222,33,72, +80,144,39,57,40,20,15,16,2,32,0,88,148,8,36,40,52,11,2,20,222, +33,73,80,144,39,58,40,20,15,16,2,11,80,143,39,59,20,15,16,2,88, +149,8,34,40,48,8,240,4,0,16,0,1,21,112,114,101,112,45,112,108,97, +110,101,116,45,114,101,115,111,108,118,101,114,33,40,224,1,0,33,74,80,144, +39,8,28,42,20,15,16,2,88,148,39,40,53,8,240,0,0,3,0,69,103, +101,116,45,100,105,114,223,0,33,75,80,144,39,8,29,42,20,15,16,2,88, +148,39,40,52,8,240,0,0,64,0,74,112,97,116,104,45,115,115,45,62,114, +107,116,223,0,33,76,80,144,39,8,30,42,20,15,16,2,88,148,8,36,40, +48,8,240,0,0,4,0,9,223,0,33,77,80,144,39,8,31,42,20,15,16, +2,88,148,39,40,48,8,240,0,128,0,0,9,223,0,33,78,80,144,39,8, +32,42,20,15,16,2,27,11,20,19,143,39,90,144,40,10,89,146,40,39,10, +20,26,96,2,22,88,148,8,36,41,57,8,32,9,224,2,1,33,79,88,148, +39,42,52,11,9,223,0,33,80,88,148,39,43,8,32,16,4,8,240,44,240, +0,0,8,240,220,241,0,0,40,39,9,224,2,1,33,96,207,80,144,39,60, +40,20,15,16,2,88,148,39,39,48,16,2,8,134,8,8,176,32,2,23,223, +0,33,97,80,144,39,8,25,40,20,15,16,2,20,28,143,88,148,8,36,39, +48,16,2,43,8,144,32,2,24,223,0,33,98,88,148,8,36,39,48,16,2, +43,8,144,32,2,24,223,0,33,99,80,144,39,8,26,40,96,29,94,2,5, +70,35,37,107,101,114,110,101,108,11,29,94,2,5,71,35,37,109,105,110,45, +115,116,120,11,2,7,2,6,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 9715); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,51,84,0,0,0,0,0,0,0, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,10,54,46,50,46,57,48,48,46,49,53,84,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,1,0,0,8, 0,18,0,24,0,38,0,52,0,64,0,84,0,98,0,113,0,126,0,131,0, -135,0,147,0,231,0,238,0,8,1,0,0,198,1,0,0,3,1,5,105,110, +135,0,147,0,231,0,238,0,8,1,0,0,199,1,0,0,3,1,5,105,110, 115,112,48,71,35,37,98,117,105,108,116,105,110,67,113,117,111,116,101,29,94, 2,3,70,35,37,107,101,114,110,101,108,11,29,94,2,3,70,35,37,101,120, 112,111,98,115,11,29,94,2,3,68,35,37,98,111,111,116,11,29,94,2,3, @@ -1559,15 +1560,15 @@ 2,1,143,2,15,16,4,2,8,39,39,2,1,143,2,15,16,4,2,9,39, 39,2,1,143,2,15,16,4,2,10,39,39,2,1,16,0,38,15,143,2,14, 2,11,18,143,16,2,143,10,16,3,9,2,11,2,13,143,11,16,3,9,9, -2,13,16,3,9,9,9,144,39,20,121,145,2,1,39,16,1,11,16,0,20, -27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9,11,11,11, -33,16,39,80,143,39,39,20,121,145,2,1,39,16,0,16,0,40,42,39,16, -0,39,16,0,39,11,11,11,16,0,16,0,16,0,39,39,40,12,11,11,16, -0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16,0, -104,2,4,2,5,29,94,2,3,71,35,37,102,111,114,101,105,103,110,11,29, -94,2,3,70,35,37,117,110,115,97,102,101,11,29,94,2,3,71,35,37,102, -108,102,120,110,117,109,11,2,6,2,7,2,8,2,9,2,10,29,94,2,3, -69,35,37,112,108,97,99,101,11,29,94,2,3,71,35,37,102,117,116,117,114, -101,115,11,9,9,9,39,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 533); +2,13,16,3,9,9,9,145,39,9,20,121,145,2,1,39,16,1,11,16,0, +20,27,15,56,9,2,2,2,2,29,11,11,11,11,11,11,11,9,9,11,11, +11,33,16,39,80,143,39,39,20,121,145,2,1,39,16,0,16,0,40,42,39, +16,0,39,16,0,39,11,11,11,16,0,16,0,16,0,39,39,40,12,11,11, +16,0,16,0,16,0,39,39,11,12,11,11,16,0,16,0,16,0,39,39,16, +0,104,2,4,2,5,29,94,2,3,71,35,37,102,111,114,101,105,103,110,11, +29,94,2,3,70,35,37,117,110,115,97,102,101,11,29,94,2,3,71,35,37, +102,108,102,120,110,117,109,11,2,6,2,7,2,8,2,9,2,10,29,94,2, +3,69,35,37,112,108,97,99,101,11,29,94,2,3,71,35,37,102,117,116,117, +114,101,115,11,9,9,9,39,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 534); } diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index 3f8ee2b2b5..e3299d8674 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -1613,6 +1613,65 @@ void scheme_shadow(Scheme_Env *env, Scheme_Object *n, Scheme_Object *val, int as scheme_add_binding_copy(id, scheme_rename_transformer_id(val), scheme_env_phase(env)); } +static void install_one_binding_name(Scheme_Hash_Table *bt, Scheme_Object *name, Scheme_Object *id, Scheme_Env *benv) +{ + if (SCHEME_SYMBOLP(name) && SCHEME_STX_SYMBOLP(id)) { + if (benv->stx_context) + id = scheme_stx_push_introduce_module_context(id, benv->stx_context); + scheme_hash_set(bt, name, id); + } +} + +void scheme_install_binding_names(Scheme_Object *binding_namess, Scheme_Env *env) +/* binding_namess has a per-phase mapping of symbosl to identifier, recorded + when `define` and `define-syntaxes` forms were compiled at the top level; + install the symbol-to-identifier mapping that was recorded during compilation + into the current namespace */ +{ + Scheme_Env *benv; + Scheme_Object *sym, *id, *table; + Scheme_Hash_Tree *ht; + Scheme_Hash_Table *bt; + intptr_t i, phase; + + if (!binding_namess) return; + + while (SCHEME_PAIRP(binding_namess)) { + table = SCHEME_CAR(binding_namess); + if (!SCHEME_PAIRP(table)) + return; + phase = SCHEME_INT_VAL(SCHEME_CAR(table)); + table = SCHEME_CDR(table); + + if (phase < 0) + return; + + benv = env; + while (phase > 0) { + scheme_prepare_exp_env(benv); + benv = benv->exp_env; + phase--; + } + + bt = scheme_get_binding_names_table(benv); + + if (SCHEME_HASHTRP(table)) { + ht = (Scheme_Hash_Tree *)table; + i = -1; + while ((i = scheme_hash_tree_next(ht, i)) != -1) { + scheme_hash_tree_index(ht, i, &sym, &id); + install_one_binding_name(bt, sym, id, benv); + } + } else if (SCHEME_VECTORP(table)) { + for (i = SCHEME_VEC_SIZE(table) >> 1; i--; ) { + install_one_binding_name(bt, SCHEME_VEC_ELS(table)[2*i], SCHEME_VEC_ELS(table)[2*i+1], benv); + } + } + + binding_namess = SCHEME_CDR(binding_namess); + } +} + /********** Auxilliary tables **********/ Scheme_Object **scheme_make_builtin_references_table(int *_unsafe_start) @@ -1917,7 +1976,7 @@ namespace_set_variable_value(int argc, Scheme_Object *argv[]) id = scheme_datum_to_syntax(argv[0], scheme_false, scheme_false, 0, 0); scheme_prepare_env_stx_context(env); id = scheme_stx_add_module_context(id, env->stx_context); - (void)scheme_global_binding(id, env); + (void)scheme_global_binding(id, env, 0); } scheme_shadow(env, argv[0], argv[1], 1); } diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 89cd6c49ca..879e6745ed 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -2093,11 +2093,16 @@ define_execute_with_dynamic_state(Scheme_Object *vec, int delta, int defmacro, g = 1; /* Special handling of 0 values for define-syntaxes: - do nothing. This makes (define-values (a b c) (values)) + just create binding. This makes (define-values (a b c) (values)) a kind of declaration form, which is useful is a, b, or c is introduced by a macro. */ - if (dm_env && !g) + if (dm_env && !g) { + for (i = SCHEME_VEC_SIZE(vec) - delta; i--; ) { + b = scheme_global_keyword_bucket(SCHEME_VEC_ELS(vec)[i+delta], dm_env); + scheme_shadow(dm_env, (Scheme_Object *)b->key, scheme_false, 1); + } return scheme_void; + } i = SCHEME_VEC_SIZE(vec) - delta; @@ -4015,7 +4020,36 @@ static int get_comp_flags(Scheme_Config *config) return comp_flags; } -static Scheme_Object *optimize_resolve_expr(Scheme_Object* o, Comp_Prefix *cp, Scheme_Object *src_insp_desc) +static void create_binding_namess(Scheme_Comp_Env *cenv) +{ + Scheme_Hash_Table *binding_namess; + binding_namess= scheme_make_hash_table(SCHEME_hash_ptr); + cenv->binding_namess = binding_namess; +} + + +static Scheme_Object *binding_namess_as_list(Scheme_Hash_Table *binding_namess) +{ + int i; + Scheme_Object *l = scheme_null, **sorted_keys; + + if (!binding_namess->count) + return scheme_null; + + sorted_keys = scheme_extract_sorted_keys((Scheme_Object *)binding_namess); + + for (i = binding_namess->count; i--; ) { + l = scheme_make_pair(scheme_make_pair(sorted_keys[i], + scheme_hash_get(binding_namess, sorted_keys[i])), + l); + } + + return l; +} + +static Scheme_Object *optimize_resolve_expr(Scheme_Object* o, Comp_Prefix *cp, + Scheme_Object *src_insp_desc, + Scheme_Object *binding_namess) { Optimize_Info *oi; Resolve_Prefix *rp; @@ -4054,6 +4088,7 @@ static Scheme_Object *optimize_resolve_expr(Scheme_Object* o, Comp_Prefix *cp, S top->max_let_depth = max_let_depth; top->code = o; top->prefix = rp; + top->binding_namess = binding_namess; return (Scheme_Object *)top; } @@ -4135,7 +4170,9 @@ static void *compile_k(void) cenv = scheme_new_comp_env(genv, insp, frame_scopes, SCHEME_TOPLEVEL_FRAME - | SCHEME_KEEP_SCOPES_FRAME); + | SCHEME_KEEP_SCOPES_FRAME + | SCHEME_TMP_TL_BIND_FRAME); + create_binding_namess(cenv); if (rib) { cenv->expand_result_adjust = scheme_stx_push_introduce_module_context; @@ -4192,7 +4229,7 @@ static void *compile_k(void) } else { /* We want to simply compile `form', but we have to loop in case an expression is lifted in the process of compiling: */ - Scheme_Object *l, *prev_o = NULL; + Scheme_Object *l, *prev_o = NULL, *binding_namess; int max_let_depth; while (1) { @@ -4253,11 +4290,14 @@ static void *compile_k(void) rp = scheme_remap_prefix(rp, ri); + binding_namess = binding_namess_as_list(cenv->binding_namess); + top = MALLOC_ONE_TAGGED(Scheme_Compilation_Top); top->iso.so.type = scheme_compilation_top_type; top->max_let_depth = max_let_depth; top->code = o; top->prefix = rp; + top->binding_namess = binding_namess; if (recompile_every_compile) { int i; @@ -4418,6 +4458,8 @@ static void *eval_k(void) v = scheme_eval_clone(v); rp = scheme_prefix_eval_clone(top->prefix); + scheme_install_binding_names(top->binding_namess, env); + save_runstack = scheme_push_prefix(env, rp, NULL, NULL, 0, env->phase, NULL, scheme_false); if (as_tail) { @@ -4913,7 +4955,8 @@ static Scheme_Object *recompile_top(Scheme_Object *top) printf("%s\n\n", scheme_print_to_string(code, NULL)); #endif - top = optimize_resolve_expr(code, cp, ((Scheme_Compilation_Top*)top)->prefix->src_insp_desc); + top = optimize_resolve_expr(code, cp, ((Scheme_Compilation_Top*)top)->prefix->src_insp_desc, + ((Scheme_Compilation_Top*)top)->binding_namess); return top; } @@ -5003,7 +5046,7 @@ scheme_make_lifted_defn(Scheme_Object *sys_wraps, Scheme_Object **_ids, Scheme_O /* Registers scoped ids: */ for (ids = *_ids; !SCHEME_NULLP(ids); ids = SCHEME_CDR(ids)) { id = SCHEME_CAR(ids); - (void)scheme_global_binding(id, env->genv); + (void)scheme_global_binding(id, env->genv, 0); } l = icons(scheme_datum_to_syntax(define_values_symbol, scheme_false, sys_wraps, 0, 0), diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 9f17ebb3c3..dd3ae0e21b 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -93,6 +93,8 @@ static Scheme_Object *read_module(Scheme_Object *obj); static Scheme_Object *read_top_level_require(Scheme_Object *obj); static Scheme_Object *write_top_level_require(Scheme_Object *obj); +static Scheme_Object *ht_to_vector(Scheme_Object *ht, int delay); + void scheme_init_marshal(Scheme_Env *env) { scheme_install_type_writer(scheme_application_type, write_application); @@ -296,6 +298,22 @@ static Scheme_Object *read_letrec(Scheme_Object *obj) return (Scheme_Object *)lr; } +static Scheme_Object *binding_namess_to_vectors(Scheme_Object *l) +{ + Scheme_Object *r = scheme_null; + + if (!l) return scheme_null; + + while (!SCHEME_NULLP(l)) { + r = cons(cons(SCHEME_CAR(SCHEME_CAR(l)), + ht_to_vector(SCHEME_CDR(SCHEME_CAR(l)), 0)), + r); + l = SCHEME_CDR(l); + } + + return r; +} + static Scheme_Object *write_top(Scheme_Object *obj) { Scheme_Compilation_Top *top = (Scheme_Compilation_Top *)obj; @@ -307,8 +325,9 @@ static Scheme_Object *write_top(Scheme_Object *obj) NULL); return cons(scheme_make_integer(top->max_let_depth), - cons((Scheme_Object *)top->prefix, - scheme_protect_quote(top->code))); + cons(binding_namess_to_vectors(top->binding_namess), + cons((Scheme_Object *)top->prefix, + scheme_protect_quote(top->code)))); } static Scheme_Object *read_top(Scheme_Object *obj) @@ -321,6 +340,9 @@ static Scheme_Object *read_top(Scheme_Object *obj) top->max_let_depth = SCHEME_INT_VAL(SCHEME_CAR(obj)); obj = SCHEME_CDR(obj); if (!SCHEME_PAIRP(obj)) return NULL; + top->binding_namess = SCHEME_CAR(obj); /* checking is in scheme_install_binding_names() */ + obj = SCHEME_CDR(obj); + if (!SCHEME_PAIRP(obj)) return NULL; top->prefix = (Resolve_Prefix *)SCHEME_CAR(obj); top->code = SCHEME_CDR(obj); if (!SAME_TYPE(SCHEME_TYPE(top->prefix), scheme_resolve_prefix_type)) @@ -1253,7 +1275,7 @@ static Scheme_Object *read_resolve_prefix(Scheme_Object *obj) return (Scheme_Object *)rp; } -static Scheme_Object *ht_to_vector(Scheme_Object *ht) +static Scheme_Object *ht_to_vector(Scheme_Object *ht, int delay) /* recurs for values in hash table; we assume that such nesting is shallow */ { intptr_t i, j, c; @@ -1292,8 +1314,8 @@ static Scheme_Object *ht_to_vector(Scheme_Object *ht) k = sorted_keys[i]; val = scheme_hash_tree_get(t, k); if (SCHEME_HASHTRP(val) || SCHEME_HASHTP(val)) - val = ht_to_vector(val); - else if (!SAME_OBJ(val, scheme_true)) + val = ht_to_vector(val, delay); + else if (delay && !SAME_OBJ(val, scheme_true)) val = make_delayed_syntax(val); SCHEME_VEC_ELS(vec)[j++] = k; SCHEME_VEC_ELS(vec)[j++] = val; @@ -1304,8 +1326,8 @@ static Scheme_Object *ht_to_vector(Scheme_Object *ht) k = sorted_keys[i]; val = scheme_hash_get(t, k); if (SCHEME_HASHTRP(val) || SCHEME_HASHTP(val)) - val = ht_to_vector(val); - else if (!SAME_OBJ(val, scheme_true)) + val = ht_to_vector(val, delay); + else if (delay && !SAME_OBJ(val, scheme_true)) val = make_delayed_syntax(val); SCHEME_VEC_ELS(vec)[j++] = k; SCHEME_VEC_ELS(vec)[j++] = val; @@ -1501,9 +1523,9 @@ static Scheme_Object *write_module(Scheme_Object *obj) l = cons((m->phaseless ? scheme_true : scheme_false), l); - l = cons(ht_to_vector(m->other_binding_names), l); - l = cons(ht_to_vector(m->et_binding_names), l); - l = cons(ht_to_vector(m->binding_names), l); + l = cons(ht_to_vector(m->other_binding_names, 1), l); + l = cons(ht_to_vector(m->et_binding_names, 1), l); + l = cons(ht_to_vector(m->binding_names, 1), l); l = cons(m->me->src_modidx, l); l = cons(scheme_resolved_module_path_value(m->modsrc), l); diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index e16754cbcf..b1081f425c 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7939,7 +7939,7 @@ static Scheme_Object *add_lifted_defn(Scheme_Object *data, Scheme_Object **_ids, id = introduce_to_module_context(id, rn); - name = scheme_global_binding(id, env->genv); + name = scheme_global_binding(id, env->genv, 0); /* Create the bucket, indicating that the name will be defined: */ scheme_add_global_symbol(name, scheme_undefined, env->genv); @@ -8979,7 +8979,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ } /* Generate symbol for this binding: */ - name = scheme_global_binding(name, env->genv); + name = scheme_global_binding(name, env->genv, 0); /* Create the bucket, indicating that the name will be defined: */ scheme_add_global_symbol(name, scheme_undefined, env->genv); @@ -9086,7 +9086,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ } /* Generate symbol for this binding: */ - name = scheme_global_binding(name, env->genv); + name = scheme_global_binding(name, env->genv, 0); if (!SAME_OBJ(SCHEME_STX_VAL(orig_name), name) || !scheme_stx_equal_module_context(orig_name, env->genv->module->rn_stx)) @@ -11864,7 +11864,7 @@ void add_single_require(Scheme_Module_Exports *me, /* from module */ modname = scheme_module_resolve(modidx, 1); menv = scheme_module_access(modname, orig_env, 0); val = scheme_lookup_in_table(menv->toplevel, (char *)exsns[j]); - b = scheme_global_bucket(scheme_global_binding(iname, orig_env), orig_env); + b = scheme_global_bucket(scheme_global_binding(iname, orig_env, 0), orig_env); scheme_set_global_bucket(((copy_vars == 2) ? "namespace-require/constant" : "namespace-require/copy"), diff --git a/racket/src/racket/src/mzmark_compenv.inc b/racket/src/racket/src/mzmark_compenv.inc index 6d8bed0805..b62c6324bf 100644 --- a/racket/src/racket/src/mzmark_compenv.inc +++ b/racket/src/racket/src/mzmark_compenv.inc @@ -24,6 +24,9 @@ static int mark_comp_env_MARK(void *p, struct NewGC *gc) { gcMARK2(e->use, gc); gcMARK2(e->lifts, gc); + gcMARK2(e->bindings, gc); + + gcMARK2(e->binding_namess, gc); gcMARK2(e->expand_result_adjust_arg, gc); @@ -50,6 +53,9 @@ static int mark_comp_env_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(e->use, gc); gcFIXUP2(e->lifts, gc); + gcFIXUP2(e->bindings, gc); + + gcFIXUP2(e->binding_namess, gc); gcFIXUP2(e->expand_result_adjust_arg, gc); diff --git a/racket/src/racket/src/mzmark_type.inc b/racket/src/racket/src/mzmark_type.inc index 605e38e480..a91c8c8d03 100644 --- a/racket/src/racket/src/mzmark_type.inc +++ b/racket/src/racket/src/mzmark_type.inc @@ -2311,6 +2311,7 @@ static int namespace_val_MARK(void *p, struct NewGC *gc) { gcMARK2(e->access_insp, gc); gcMARK2(e->stx_context, gc); + gcMARK2(e->tmp_bind_scope, gc); gcMARK2(e->syntax, gc); gcMARK2(e->exp_env, gc); @@ -2357,6 +2358,7 @@ static int namespace_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(e->access_insp, gc); gcFIXUP2(e->stx_context, gc); + gcFIXUP2(e->tmp_bind_scope, gc); gcFIXUP2(e->syntax, gc); gcFIXUP2(e->exp_env, gc); @@ -2450,6 +2452,7 @@ static int compilation_top_val_MARK(void *p, struct NewGC *gc) { Scheme_Compilation_Top *t = (Scheme_Compilation_Top *)p; gcMARK2(t->code, gc); gcMARK2(t->prefix, gc); + gcMARK2(t->binding_namess, gc); return gcBYTES_TO_WORDS(sizeof(Scheme_Compilation_Top)); @@ -2459,6 +2462,7 @@ static int compilation_top_val_FIXUP(void *p, struct NewGC *gc) { Scheme_Compilation_Top *t = (Scheme_Compilation_Top *)p; gcFIXUP2(t->code, gc); gcFIXUP2(t->prefix, gc); + gcFIXUP2(t->binding_namess, gc); return gcBYTES_TO_WORDS(sizeof(Scheme_Compilation_Top)); diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 6127359044..96eed8c542 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -932,6 +932,7 @@ namespace_val { gcMARK2(e->access_insp, gc); gcMARK2(e->stx_context, gc); + gcMARK2(e->tmp_bind_scope, gc); gcMARK2(e->syntax, gc); gcMARK2(e->exp_env, gc); @@ -988,6 +989,7 @@ compilation_top_val { Scheme_Compilation_Top *t = (Scheme_Compilation_Top *)p; gcMARK2(t->code, gc); gcMARK2(t->prefix, gc); + gcMARK2(t->binding_namess, gc); size: gcBYTES_TO_WORDS(sizeof(Scheme_Compilation_Top)); @@ -1279,6 +1281,9 @@ mark_comp_env { gcMARK2(e->use, gc); gcMARK2(e->lifts, gc); + gcMARK2(e->bindings, gc); + + gcMARK2(e->binding_namess, gc); gcMARK2(e->expand_result_adjust_arg, gc); diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 12580e462d..4bb6a034c7 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1413,6 +1413,8 @@ typedef struct { mzshort max_let_depth; Scheme_Object *code; struct Resolve_Prefix *prefix; /* NULL => a wrapper for a JITted module in `code' */ + Scheme_Object *binding_namess; /* list of to hash of to ; + additions to the top-level bindings table */ } Scheme_Compilation_Top; /* A `let', `let*', or `letrec' form is compiled to the intermediate @@ -2582,6 +2584,9 @@ typedef struct Scheme_Comp_Env Scheme_Object *lifts; + Scheme_Hash_Table *binding_namess; /* -> ( -> ); additions to the environment's + bindings table made during a particular compilation */ + mzshort rename_var_count; /* number of non-NULL `values' when `renames' was computed */ mzshort rename_rstart; /* leftover rstart from previous round; see env.c */ Scheme_Hash_Table *dup_check; /* table for finding colliding symbols in `values' */ @@ -3168,6 +3173,7 @@ void scheme_mark_all_use(Scheme_Comp_Env *frame); #define SCHEME_POST_BIND_FRAME (1 << 11) #define SCHEME_NESTED_MODULE_FRAME (1 << 12) #define SCHEME_KEEP_SCOPES_FRAME (1 << 13) +#define SCHEME_TMP_TL_BIND_FRAME (1 << 14) #define SCHEME_REC_BINDING_FRAME (SCHEME_TOPLEVEL_FRAME | SCHEME_MODULE_BEGIN_FRAME \ | SCHEME_INTDEF_FRAME | SCHEME_FOR_INTDEF) @@ -3285,6 +3291,8 @@ void scheme_define_parse(Scheme_Object *form, void scheme_shadow(Scheme_Env *env, Scheme_Object *n, Scheme_Object *val, int as_var); void scheme_binding_names_from_module(Scheme_Env *menv); +void scheme_install_binding_names(Scheme_Object *binding_namess, Scheme_Env *env); +Scheme_Hash_Table *scheme_get_binding_names_table(Scheme_Env *env); int scheme_prefix_depth(Resolve_Prefix *rp); Scheme_Object **scheme_push_prefix(Scheme_Env *genv, Resolve_Prefix *rp, @@ -3421,6 +3429,7 @@ struct Scheme_Env { Scheme_Object *access_insp; /* for gaining protected access */ Scheme_Object *stx_context; /* encapsulates scopes, shifts, etc. */ + Scheme_Object *tmp_bind_scope; /* for compiling top-level definitions */ Scheme_Bucket_Table *syntax; struct Scheme_Env *exp_env; @@ -3633,7 +3642,7 @@ void scheme_add_global_constant_symbol(Scheme_Object *name, Scheme_Object *v, Sc } while(0) -Scheme_Object *scheme_global_binding(Scheme_Object *id, Scheme_Env *env); +Scheme_Object *scheme_global_binding(Scheme_Object *id, Scheme_Env *env, int for_top_level); Scheme_Object *scheme_future_global_binding(Scheme_Object *id, Scheme_Env *env); Scheme_Object *scheme_sys_wraps(Scheme_Comp_Env *env); diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 06e21322b8..7cd63bcc70 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.14" +#define MZSCHEME_VERSION "6.2.900.15" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 14 +#define MZSCHEME_VERSION_W 15 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From c3f876d2f7760c0b1ca8b63736334f48db34ef80 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Sep 2015 14:09:05 -0600 Subject: [PATCH 152/381] fix bug in mashaling paths The change in commit fb8e08a2ac could lose part of a relative path. --- racket/src/racket/src/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index 7faa4bde50..38666fa394 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -5679,7 +5679,7 @@ Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir while (SCHEME_PAIRP(oe)) { if (cache) { - obj = scheme_make_pair(to_bytes(SCHEME_CAR(oe)), scheme_null); + obj = scheme_make_pair(to_bytes(SCHEME_CAR(oe)), obj); } else { a[0] = obj; a[1] = SCHEME_CAR(oe); From 06841bbaff6736739bada6369f6ef4c261b842bd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Sep 2015 17:59:19 -0600 Subject: [PATCH 153/381] doc typo and clarification --- pkgs/racket-doc/scribblings/raco/api.scrbl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/raco/api.scrbl b/pkgs/racket-doc/scribblings/raco/api.scrbl index 72db5fbe6b..0469e07eed 100644 --- a/pkgs/racket-doc/scribblings/raco/api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/api.scrbl @@ -216,7 +216,8 @@ suffixes: byte-regexp?]{ Returns a @tech[#:doc reference-doc]{regexp value} that matches paths ending -with a suffix as reported by @racket[get-module-path-suffixes].} +with a suffix as reported by @racket[get-module-suffixes]. The pattern +includes a subpatterns for the suffix without its leading @litchar{.}} @; ---------------------------------------------------------------------- From 9c51370e51f979c27decd628214dc85d9b67e423 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Sep 2015 17:59:44 -0600 Subject: [PATCH 154/381] repair `extract-base-filename/ext` and `extract-base-filename/o` --- racket/collects/dynext/file.rkt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/racket/collects/dynext/file.rkt b/racket/collects/dynext/file.rkt index 31a2536ea8..014e52f62f 100644 --- a/racket/collects/dynext/file.rkt +++ b/racket/collects/dynext/file.rkt @@ -80,9 +80,9 @@ (define (extract-base-filename/o s [program #f]) (extract 'extract-base-filename/o s program - (case (system-type) - [(unix beos macos macosx) #"o"] - [(windows) #"obj"]) + (extract-rx (case (system-type) + [(unix beos macos macosx) #"o"] + [(windows) #"obj"])) "compiled object" (extract-suffix append-object-suffix))) @@ -90,6 +90,6 @@ (extract 'extract-base-filename/ext s program - (regexp-quote (subbytes (system-type 'so-suffix) 1) #f) + (extract-rx (regexp-quote (subbytes (system-type 'so-suffix) 1) #f)) "Racket extension" (extract-suffix append-extension-suffix))) From 079f46fbc149cb17def0794047ba53baecffd2a1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 6 Sep 2015 07:59:50 -0600 Subject: [PATCH 155/381] adjust top-level handling for identifiers without `#%top` Refine the changes in 16c198805b so that `(define id ... id ... )` at the top level compiles more consistently when `id` is an identifier whose lexical context does not include `#%top`. --- .../tests/racket/namespac.rktl | 31 ++++++++++++++----- racket/src/racket/src/compenv.c | 12 +++++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/namespac.rktl b/pkgs/racket-test-core/tests/racket/namespac.rktl index 7852725e31..4b73de4ea1 100644 --- a/pkgs/racket-test-core/tests/racket/namespac.rktl +++ b/pkgs/racket-test-core/tests/racket/namespac.rktl @@ -393,15 +393,30 @@ (eval (eval '(def))) (test 1 eval '(ref))) -#| -(define-syntax-rule (m3 c-id) - (begin - (define-syntax plus #f) - (define (c-id) (compile #'(define plus plus))))) +;; When a binding is present, it takes precedence over +;; a "temporary" binding: +(parameterize ([current-namespace (make-base-namespace)]) + (eval '(require (for-syntax racket/base))) + (eval '(define-syntax-rule (m3 c-id) + (begin + (define-syntax plus #f) + (define (c-id) (compile #'(define plus plus)))))) + (eval '(m3 cdef)) + (err/rt-test (eval '(cdef)) exn:fail:syntax?)) -(m3 cdef) -(cdef) -|# +;; A "temporary" binding should work on an identifier with +;; no `#%top` in its context: +(parameterize ([current-namespace (make-base-namespace)]) + (eval '(require (for-syntax racket/base))) + (eval '(define-syntax (m3 stx) + (with-syntax ([(gen) (generate-temporaries '(gen))]) + (syntax-case stx () + [(_ id) + #'(begin + (define (gen) gen) + (define id gen))])))) + (eval '(m3 self)) + (test #t eval '(eq? self (self)))) ;; ---------------------------------------- diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index e20cfc60f9..b38bd15f7a 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -1443,9 +1443,17 @@ scheme_compile_lookup(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, *_menv = genv; if (SCHEME_STXP(find_id)) { - if (flags & SCHEME_NULL_FOR_UNBOUND) - return NULL; find_global_id = scheme_future_global_binding(find_id, env->genv); + if (!SAME_OBJ(find_global_id, SCHEME_STX_VAL(find_id)) + && SCHEME_FALSEP(binding)) { + /* Since we got a symbol back, there's at least a "temporary" + top-level binding for the identifier in the current namespace */ + binding = scheme_make_vector(3, NULL); + SCHEME_VEC_ELS(binding)[0] = find_global_id; + SCHEME_VEC_ELS(binding)[1] = (env->genv->module ? env->genv->module->modname : scheme_false); + SCHEME_VEC_ELS(binding)[2] = scheme_env_phase(env->genv); + } else if (flags & SCHEME_NULL_FOR_UNBOUND) + return NULL; } else find_global_id = find_id; From 3018417249f22c5d570b7f6279d4ad7ff6e9bb16 Mon Sep 17 00:00:00 2001 From: Spencer Florence Date: Fri, 4 Sep 2015 16:03:54 -0500 Subject: [PATCH 156/381] added args checking to prefix functions --- pkgs/racket-test-core/tests/racket/list.rktl | 1 + racket/collects/racket/list.rkt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/list.rktl b/pkgs/racket-test-core/tests/racket/list.rktl index d7d3dacb45..cc185354c4 100644 --- a/pkgs/racket-test-core/tests/racket/list.rktl +++ b/pkgs/racket-test-core/tests/racket/list.rktl @@ -615,6 +615,7 @@ (test '((a b c d) () ()) split*-list '(a b c d) '(a b c d)) (test '((1 2) (3 4) (4 3)) split*-list '(1 2 3 4) '(1 2 4 3) =) (err/rt-test (split*-list '() '() #f)) +(err/rt-test (take-common-prefix 1 1)) ;; ---------- remf / remf* ---------- diff --git a/racket/collects/racket/list.rkt b/racket/collects/racket/list.rkt index a0b7721732..1717f6f57c 100644 --- a/racket/collects/racket/list.rkt +++ b/racket/collects/racket/list.rkt @@ -287,6 +287,10 @@ ;; lists, and return a matching number of values. (define (internal-split-common-prefix as bs same? keep-prefix? name) + (unless (list? as) + (raise-argument-error name "list?" as)) + (unless (list? bs) + (raise-argument-error name "list?" bs)) (unless (and (procedure? same?) (procedure-arity-includes? same? 2)) (raise-argument-error name "(any/c any/c . -> . any/c)" same?)) From 8566c67b35255a4655c8984233b4573159e53f8a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 6 Sep 2015 12:11:55 -0600 Subject: [PATCH 157/381] make syntax-object unmarshaling more accepting Defend against certain bad encodings, but accept an encoding that includes more sharing than the built-in marshaling could create. --- racket/src/racket/src/mzmark_read.inc | 2 + racket/src/racket/src/mzmarksrc.c | 1 + racket/src/racket/src/read.c | 3 ++ racket/src/racket/src/schpriv.h | 3 +- racket/src/racket/src/syntax.c | 64 ++++++++++++++++++++++----- 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/racket/src/racket/src/mzmark_read.inc b/racket/src/racket/src/mzmark_read.inc index 1675c8d255..174103aba0 100644 --- a/racket/src/racket/src/mzmark_read.inc +++ b/racket/src/racket/src/mzmark_read.inc @@ -167,6 +167,7 @@ static int mark_unmarshal_tables_SIZE(void *p, struct NewGC *gc) { static int mark_unmarshal_tables_MARK(void *p, struct NewGC *gc) { Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcMARK2(ut->rns, gc); + gcMARK2(ut->multi_scope_pairs, gc); gcMARK2(ut->rp, gc); gcMARK2(ut->decoded, gc); return @@ -176,6 +177,7 @@ static int mark_unmarshal_tables_MARK(void *p, struct NewGC *gc) { static int mark_unmarshal_tables_FIXUP(void *p, struct NewGC *gc) { Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcFIXUP2(ut->rns, gc); + gcFIXUP2(ut->multi_scope_pairs, gc); gcFIXUP2(ut->rp, gc); gcFIXUP2(ut->decoded, gc); return diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 96eed8c542..61a22b3cc0 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -2343,6 +2343,7 @@ mark_unmarshal_tables { mark: Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcMARK2(ut->rns, gc); + gcMARK2(ut->multi_scope_pairs, gc); gcMARK2(ut->rp, gc); gcMARK2(ut->decoded, gc); size: diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 94f944dcaf..156e711f12 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -4439,6 +4439,9 @@ static void make_ut(CPort *port) rht = scheme_make_hash_table(SCHEME_hash_ptr); port->ut->rns = rht; + + rht = scheme_make_hash_table(SCHEME_hash_ptr); + port->ut->multi_scope_pairs = rht; } /* Since read_compact_number is called often, we want it to be diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 4bb6a034c7..fb8ce29794 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -3371,8 +3371,9 @@ void scheme_marshal_push_refs(Scheme_Marshal_Tables *mt); void scheme_marshal_pop_refs(Scheme_Marshal_Tables *mt, int keep); typedef struct Scheme_Unmarshal_Tables { - MZTAG_IF_REQUIRED + MZTAG_IF_REQUIRED Scheme_Hash_Table *rns; + Scheme_Hash_Table *multi_scope_pairs; /* records conversions */ struct CPort *rp; char *decoded; mzlonglong bytecode_hash; diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 97083f6763..815d967465 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -6613,7 +6613,8 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, Scheme_Unmarshal_Tables *ut) { Scheme_Hash_Table *multi_scope; - Scheme_Object *l, *mm_l; + Scheme_Object *l, *mm_l, *first = NULL, *last = NULL; + Scheme_Object *l_first, *l_last, *p; mm_l = multi_scopes; @@ -6622,27 +6623,66 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, if (SCHEME_FALLBACKP(l)) l = SCHEME_FALLBACK_FIRST(l); + l_first = scheme_null; + l_last = NULL; for (; !SCHEME_NULLP(l); l = SCHEME_CDR(l)) { + int stop; + if (!SCHEME_PAIRP(l)) return_NULL; if (!SCHEME_PAIRP(SCHEME_CAR(l))) return_NULL; - if (SCHEME_VECTORP(SCHEME_CAR(SCHEME_CAR(l)))) { - multi_scope = vector_to_multi_scope(SCHEME_CAR(SCHEME_CAR(l)), ut); - if (!multi_scope) return_NULL; - SCHEME_CAR(SCHEME_CAR(l)) = (Scheme_Object *)multi_scope; - if (!SCHEME_PHASE_SHIFTP(SCHEME_CDR(SCHEME_CAR(l)))) return_NULL; - } else { - /* rest of list must be converted already, too */ + + p = scheme_hash_get(ut->multi_scope_pairs, l); + if (!p) { + p = scheme_hash_get(ut->multi_scope_pairs, SCHEME_CAR(l)); + if (p) { + p = scheme_make_pair(p, scheme_null); + } else { + if (SCHEME_VECTORP(SCHEME_CAR(SCHEME_CAR(l)))) { + multi_scope = vector_to_multi_scope(SCHEME_CAR(SCHEME_CAR(l)), ut); + if (!multi_scope) return_NULL; + if (!SCHEME_PHASE_SHIFTP(SCHEME_CDR(SCHEME_CAR(l)))) return_NULL; + p = scheme_make_pair((Scheme_Object *)multi_scope, + SCHEME_CDR(SCHEME_CAR(l))); + scheme_hash_set(ut->multi_scope_pairs, SCHEME_CAR(l), p); + } else + return_NULL; + } + scheme_hash_set(ut->multi_scope_pairs, SCHEME_CAR(l), p); + p = scheme_make_pair(p, scheme_null); + stop = 0; + } else + stop = 1; + + if (l_last) + SCHEME_CDR(l_last) = p; + else + l_first = p; + l_last = p; + + if (stop) break; - } + else + scheme_hash_set(ut->multi_scope_pairs, l, p); } - if (SCHEME_FALLBACKP(mm_l)) + if (SCHEME_FALLBACKP(mm_l)) { + p = make_fallback_pair(l_first, scheme_null); + if (last) + SCHEME_FALLBACK_REST(last) = p; + else + first = p; + last = p; mm_l = SCHEME_FALLBACK_REST(mm_l); - else + } else { + if (last) + SCHEME_FALLBACK_REST(last) = l_first; + else + first = l_first; break; + } } - return multi_scopes; + return first; } static Scheme_Object *datum_to_wraps(Scheme_Object *w, From 4cb74da76c2702452c94a55a1877bcadfda8754b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 6 Sep 2015 17:18:35 -0600 Subject: [PATCH 158/381] add patch for Mac OS X build of Cairo Pull in a patch to avoid CGFontGetGlyphPath, which is deprecated. --- racket/src/native-libs/build.rkt | 4 ++ .../native-libs/patches/cgfontgetglyph.patch | 48 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 racket/src/native-libs/patches/cgfontgetglyph.patch diff --git a/racket/src/native-libs/build.rkt b/racket/src/native-libs/build.rkt index 9c2e946a53..820a2f988f 100644 --- a/racket/src/native-libs/build.rkt +++ b/racket/src/native-libs/build.rkt @@ -113,6 +113,9 @@ ;; Fix a problem with glyph extents and clipped rendering: (define-runtime-path cairo-coretext-patch "patches/cairo-coretext.patch") +;; Avoid CGFontGetGlyphPath: +(define-runtime-path cairo-cgfontgetglpyh-patch "patches/cgfontgetglyph.patch") + ;; Hack to workaround broken Courier New in Mac OS X 10.{7.8}: (define-runtime-path courier-new-patch "patches/courier-new.patch") @@ -412,6 +415,7 @@ '("--enable-xlib=no") null) #:patches (list cairo-coretext-patch + cairo-cgfontgetglpyh-patch courier-new-patch win32cairofallback-patch))] [("harfbuzz") (config #:depends '("fontconfig" "freetype" "cairo") diff --git a/racket/src/native-libs/patches/cgfontgetglyph.patch b/racket/src/native-libs/patches/cgfontgetglyph.patch new file mode 100644 index 0000000000..bde65a327e --- /dev/null +++ b/racket/src/native-libs/patches/cgfontgetglyph.patch @@ -0,0 +1,48 @@ +diff -u -r old/cairo-1.12.16/src/cairo-quartz-font.c new/cairo-1.12.16/src/cairo-quartz-font.c +--- old/cairo-1.12.16/src/cairo-quartz-font.c 2015-09-06 17:07:39.000000000 -0600 ++++ new/cairo-1.12.16/src/cairo-quartz-font.c 2015-09-06 17:09:06.000000000 -0600 +@@ -81,9 +81,6 @@ + static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL; + static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL; + +-/* Not public in the least bit */ +-static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = NULL; +- + /* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */ + typedef struct { + int ascent; +@@ -131,7 +128,6 @@ + /* These have the same name in 10.4 and 10.5 */ + CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm"); + CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances"); +- CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath"); + + CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics"); + CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent"); +@@ -148,7 +144,6 @@ + CGFontGetGlyphsForUnicharsPtr && + CGFontGetUnitsPerEmPtr && + CGFontGetGlyphAdvancesPtr && +- CGFontGetGlyphPathPtr && + (CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr))) + _cairo_quartz_font_symbols_present = TRUE; + +@@ -592,6 +587,7 @@ + CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); + CGAffineTransform textMatrix; + CGPathRef glyphPath; ++ CTFontRef ctFont; + cairo_path_fixed_t *path; + + if (glyph == INVALID_GLYPH) { +@@ -606,7 +602,9 @@ + -font->base.scale.yy, + 0, 0); + +- glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph); ++ ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 1.0, NULL, NULL); ++ glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix); ++ CFRelease (ctFont); + if (!glyphPath) + return CAIRO_INT_STATUS_UNSUPPORTED; + From c1ef6b999d2296efd4fb703555d13bb7cbbff8e4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 07:48:43 -0600 Subject: [PATCH 159/381] fix documentation's contract for `syntax-track-origin` --- pkgs/racket-doc/scribblings/reference/stx-props.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-props.scrbl b/pkgs/racket-doc/scribblings/reference/stx-props.scrbl index 694abc4578..e097f2412c 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-props.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-props.scrbl @@ -124,7 +124,7 @@ in @racket[stx]. @tech{Uninterned} symbols (see @secref["symbols"]) are not included in the result list.} -@defproc[(syntax-track-origin [new-stx syntax?] [orig-stx syntax?] [id-stx syntax?]) +@defproc[(syntax-track-origin [new-stx syntax?] [orig-stx syntax?] [id-stx identifier?]) any]{ Adds properties to @racket[new-stx] in the same way that macro From 5ca752c92b60991d389359040b490382fa06fd16 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 08:22:21 -0600 Subject: [PATCH 160/381] fix problems with internal calls to `syntax-track-origin` --- racket/src/racket/src/compile.c | 7 +++---- racket/src/racket/src/syntax.c | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 5d8105ff1d..c2bff0ce34 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -4482,9 +4482,8 @@ static Scheme_Object *install_alt_from_rename(Scheme_Object *first, Scheme_Objec Scheme_Object *tail; tail = scheme_stx_taint_disarm(first, NULL); tail = SCHEME_STX_CDR(tail); - alt_first = scheme_datum_to_syntax(scheme_make_pair(alt_first, tail), - first, first, 0, 1); - return scheme_stx_track(alt_first, first, first); + return scheme_datum_to_syntax(scheme_make_pair(alt_first, tail), + first, first, 0, 1); } else return alt_first; } else @@ -4698,7 +4697,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, if (scheme_stx_has_empty_wraps(form, scheme_env_phase(env->genv)) && same_effective_env(SCHEME_PTR2_VAL(var), env)) { /* FIXME [Ryan?]: this needs EXPAND_OBSERVE callbacks. */ - form = scheme_stx_track(SCHEME_PTR1_VAL(var), form, form); + form = scheme_stx_track(SCHEME_PTR1_VAL(var), form, NULL); if (!rec[drec].comp) { /* Already fully expanded. */ return form; diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 815d967465..2d3c57a4f4 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -536,6 +536,8 @@ Scheme_Object *scheme_stx_track(Scheme_Object *naya, Scheme_Object *e1, *key, *val; mzlonglong i; + STX_ASSERT(!origin || SCHEME_STX_SYMBOLP(origin)); + if (nstx->props) ne = nstx->props; else From e1333d061679beb699895b308debc5005d164a70 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 08:28:08 -0600 Subject: [PATCH 161/381] fix `compilation-top` contract in docs The associated change in the "zo-lib" package fixes #1038. --- pkgs/racket-doc/scribblings/raco/zo-struct.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl index bc92d31f64..5de07392c4 100644 --- a/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl +++ b/pkgs/racket-doc/scribblings/raco/zo-struct.scrbl @@ -37,7 +37,7 @@ structures that are produced by @racket[zo-parse] and consumed by @defstruct+[(compilation-top zo) ([max-let-depth exact-nonnegative-integer?] [binding-namess (hash/c exact-nonnegative-integer? - (hash/c symbol? identifier?))] + (hash/c symbol? stx?))] [prefix prefix?] [code (or/c form? any/c)])]{ Wraps compiled code. From e0f2d9c0d642f58becfc03988b77207e8e307617 Mon Sep 17 00:00:00 2001 From: Brian Lachance Date: Mon, 7 Sep 2015 12:05:36 -0400 Subject: [PATCH 162/381] Fix make-contract example to show the correct contract violation There was a duplicate quote around `given:' which caused a violation in make-contract's internals. --- pkgs/racket-doc/scribblings/reference/contracts.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index f1dbde8969..0ba6295bd7 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -1979,7 +1979,7 @@ to determine if this is a contract that accepts only @racket[list?] values. (λ (x) (range (f (domain x)))) (raise-blame-error b f - '(expected "a function of one argument" 'given: "~e") + '(expected "a function of one argument" given: "~e") f))))))) (contract int->int/c "not fun" 'positive 'negative) (define halve From 3963f300702f9cd165ff996a4582df9506ba499e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 11:58:41 -0600 Subject: [PATCH 163/381] document new `configure-runtime` behavior of `raco test` --- pkgs/racket-doc/scribblings/raco/test.scrbl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/racket-doc/scribblings/raco/test.scrbl b/pkgs/racket-doc/scribblings/raco/test.scrbl index cd4e0a4a94..f3560b7b62 100644 --- a/pkgs/racket-doc/scribblings/raco/test.scrbl +++ b/pkgs/racket-doc/scribblings/raco/test.scrbl @@ -89,6 +89,14 @@ The @exec{raco test} command accepts several flags: --- When multiple submodule names are provided with @Flag{s} or @DFlag{submodule}, runs only the first available submodule.} +@item{@DFlag{configure-runtime} + --- Run a @racketidfont{configure-runtime} submodule (if any) of + each specified module before the module or a + submodule is run. This mode is the default when only a single + module is provided or when @DFlag{process} or @DFlag{place} + mode is specified, unless a submodule name is provided + via @Flag{s} or @DFlag{submodule}.} + @item{@DFlag{direct} --- Runs each test in a thread. This mode is the default if a single file is specified. Multiple tests can interfere with From d705e928ac8d17aa3213cf478c3c7c1954bf39bd Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 7 Sep 2015 15:27:45 -0500 Subject: [PATCH 164/381] Add a `mode` argument to `pretty-format`. ... which controls whether it uses `print`, `write` or `display`. Obsoletes most of `unstable/pretty`. --- .../scribblings/reference/pretty-print.scrbl | 11 +++++-- .../racket-test-core/tests/racket/pretty.rktl | 30 ++++++++++++++++++- racket/collects/racket/pretty.rkt | 24 ++++++++------- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl b/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl index 95e07af13d..5ceeb576f9 100644 --- a/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl +++ b/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl @@ -54,14 +54,21 @@ Same as @racket[pretty-print], but @racket[v] is printed like @racket[display] instead of like @racket[print].} -@defproc[(pretty-format [v any/c] [columns exact-nonnegative-integer? (pretty-print-columns)]) +@defproc[(pretty-format [v any/c] [columns exact-nonnegative-integer? (pretty-print-columns)] + [#:mode mode (or/c 'print 'write 'display) 'print]) string?]{ Like @racket[pretty-print], except that it returns a string containing the pretty-printed value, rather than sending the output to a port. The optional argument @racket[columns] argument is used to -parameterize @racket[pretty-print-columns].} +parameterize @racket[pretty-print-columns]. + +The keyword argument @racket[mode] controls whether printing is done like +either @racket[pretty-print] (the default), @racket[pretty-write] or +@racket[pretty-display]. + +@history[#:changed "6.2.900.15" @elem{Added a @racket[mode] argument.}]} @defproc[(pretty-print-handler [v any/c]) void?]{ diff --git a/pkgs/racket-test-core/tests/racket/pretty.rktl b/pkgs/racket-test-core/tests/racket/pretty.rktl index 347f418a0e..327c4a0b58 100644 --- a/pkgs/racket-test-core/tests/racket/pretty.rktl +++ b/pkgs/racket-test-core/tests/racket/pretty.rktl @@ -425,7 +425,35 @@ '(1 2 3 4 5)))]) (try-print pretty-print val 10 "(list\n (DUO\n '(a\n b\n c\n d\n e)\n '(1\n 2\n 3\n 4\n 5)))\n") (try-print pretty-write val 10 "((DUO\n (a\n b\n c\n d\n e)\n (1\n 2\n 3\n 4\n 5)))\n") - (try-print pretty-display val 10 "((DUO\n (a\n b\n c\n d\n e)\n (1\n 2\n 3\n 4\n 5)))\n")))) + (try-print pretty-display val 10 "((DUO\n (a\n b\n c\n d\n e)\n (1\n 2\n 3\n 4\n 5)))\n"))) + + (test "(DUO 1 2)" + pretty-format (duo 1 2) 40 #:mode 'print) + (test "(DUO 1 2)" + pretty-format (duo 1 2) 40 #:mode 'write) + (test "(DUO 1 2)" + pretty-format (duo 1 2) 40 #:mode 'display) + + (test "(DUO \"a\" 'b)" + pretty-format (duo "a" 'b) #:mode 'print 40) + (test "(DUO \"a\" b)" + pretty-format (duo "a" 'b) #:mode 'write 40) + (test "(DUO a b)" + pretty-format (duo "a" 'b) #:mode 'display 40) + + (test "(DUO\n \"abcdefghijklmno\"\n 'b)" + pretty-format (duo "abcdefghijklmno" 'b) 20 #:mode 'print) + (test "(DUO\n \"abcdefghijklmno\"\n b)" + pretty-format (duo "abcdefghijklmno" 'b) 20 #:mode 'write) + (test "(DUO\n abcdefghijklmno\n b)" + pretty-format (duo "abcdefghijklmno" 'b) 20 #:mode 'display) + + (test "(list\n (DUO\n \"abcdefghijklmno\"\n 'b))" + pretty-format (list (duo "abcdefghijklmno" 'b)) 20 #:mode 'print) + (test "((DUO\n \"abcdefghijklmno\"\n b))" + pretty-format (list (duo "abcdefghijklmno" 'b)) 20 #:mode 'write) + (test "((DUO\n abcdefghijklmno\n b))" + pretty-format (list (duo "abcdefghijklmno" 'b)) 20 #:mode 'display)) ;; ---------------------------------------- diff --git a/racket/collects/racket/pretty.rkt b/racket/collects/racket/pretty.rkt index 13ff22ec0e..786b75a108 100644 --- a/racket/collects/racket/pretty.rkt +++ b/racket/collects/racket/pretty.rkt @@ -1622,17 +1622,19 @@ ;; Print as a fraction. (number->string x)))))))])) - (define pretty-format - (case-lambda - [(t) (pretty-format t (pretty-print-columns))] - [(t w) - (parameterize ([pretty-print-columns w]) - (let ([op (open-output-string)]) - (pretty-print t op) - (let ([s (get-output-string op)]) - (if (eq? w 'infinity) - s - (substring s 0 (- (string-length s) 1))))))])) + (define (pretty-format t [w (pretty-print-columns)] #:mode [mode 'print]) + (parameterize ([pretty-print-columns w]) + (let ([op (open-output-string)]) + ((case mode + [(print) pretty-print] + [(write) pretty-write] + [(display) pretty-display] + [else (raise-argument-error 'pretty-format "(or/c 'print 'write display)" mode)]) + t op) + (let ([s (get-output-string op)]) + (if (eq? w 'infinity) + s + (substring s 0 (- (string-length s) 1))))))) ) From 27791ebab74fa3628f5f9d014766168a95edde1b Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Mon, 7 Sep 2015 14:11:56 -0300 Subject: [PATCH 165/381] Remove ignored call/cc Reduce (call/cc (lambda () body ...)) to (begin body ...) --- .../tests/racket/optimize.rktl | 10 +++++ racket/src/racket/src/optimize.c | 44 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 765556b6c2..6ee590e510 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -3539,6 +3539,16 @@ (set! f 0)) #f) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check that the unused continuations are removed + +(test-comp '(call-with-current-continuation (lambda (ignored) 5)) + 5) +(test-comp '(call-with-composable-continuation (lambda (ignored) 5)) + 5) +(test-comp '(call-with-escape-continuation (lambda (ignored) 5)) + 5) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check splitting of definitions (test-comp `(module m racket/base diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index e3ae38b326..51b90cbca0 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -3062,6 +3062,46 @@ static Scheme_Object *try_reduce_predicate(Scheme_Object *rator, Scheme_Object * return make_discarding_sequence(rand, (matches ? scheme_true : scheme_false), info, id_offset); } +static Scheme_Object *check_ignored_call_cc(Scheme_Object *rator, Scheme_Object *rand, + Optimize_Info *info, int context) +/* Convert (call/cc (lambda (ignored) body ...)) to (begin body ...) */ +{ + if (SCHEME_PRIMP(rator) + && (IS_NAMED_PRIM(rator, "call-with-current-continuation") + || IS_NAMED_PRIM(rator, "call-with-composable-continuation") + || IS_NAMED_PRIM(rator, "call-with-escape-continuation"))) { + int rand_flags; + Scheme_Object *proc; + proc = lookup_constant_proc(info, rand, 0); + if (!proc) + proc = optimize_for_inline(info, rand, 1, NULL, NULL, NULL, &rand_flags, context, 0, 0); + + if (proc && SAME_TYPE(SCHEME_TYPE(proc), scheme_compiled_unclosed_procedure_type)) { + Scheme_Closure_Data *data = (Scheme_Closure_Data *)proc; + if (data->num_params == 1) { + Closure_Info *cl = (Closure_Info *)data->closure_map; + if (((cl->local_flags[0] & SCHEME_USE_COUNT_MASK) >> SCHEME_USE_COUNT_SHIFT) == 0) { + Scheme_Object *expr; + info->vclock++; + expr = make_application_2(rand, scheme_void, info); + if (IS_NAMED_PRIM(rator, "call-with-escape-continuation")) { + Scheme_Sequence *seq; + + seq = scheme_malloc_sequence(1); + seq->so.type = scheme_begin0_sequence_type; + seq->count = 1; + seq->array[0] = expr; + + expr = (Scheme_Object *)seq; + } + return scheme_optimize_expr(expr, info, context); + } + } + } + } + return NULL; +} + static Scheme_Object *make_optimize_prim_application2(Scheme_Object *prim, Scheme_Object *rand, Optimize_Info *info, int context) /* make (prim rand) and optimize it. rand must be already optimized */ @@ -3091,6 +3131,10 @@ static Scheme_Object *optimize_application2(Scheme_Object *o, Optimize_Info *inf if (le) return le; + le = check_ignored_call_cc(app->rator, app->rand, info, context); + if (le) + return le; + le = optimize_for_inline(info, app->rator, 1, NULL, app, NULL, &rator_flags, context, 0, 0); if (le) return le; From 0ab94dd3e48cd4b0d5dcbef7b097cc29084e2aa4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 13:28:30 -0600 Subject: [PATCH 166/381] force GC more appropriately on phantom bytes When the number of bytes recorded via phantom bytes approaches memory use at the last GC, force a garbage collection. --- racket/src/racket/gc2/newgc.c | 13 +++++++++---- racket/src/racket/gc2/newgc.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index ca08b0d627..c919286006 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -1667,11 +1667,11 @@ int GC_allocate_phantom_bytes(intptr_t request_size_bytes) #endif if ((request_size_bytes > 0) - && ((gc->phantom_count + request_size_bytes) < gc->phantom_count)) + && ((gc->gen0_phantom_count + request_size_bytes) < gc->gen0_phantom_count)) /* overflow */ return 1; - gc->phantom_count += request_size_bytes; + gc->gen0_phantom_count += request_size_bytes; /* adjust `gc->memory_in_use', but protect against {over,under}flow: */ if (request_size_bytes < 0) { request_size_bytes = -request_size_bytes; @@ -1680,6 +1680,10 @@ int GC_allocate_phantom_bytes(intptr_t request_size_bytes) } else gc->memory_in_use = add_no_overflow(gc->memory_in_use, request_size_bytes); + /* If we've allocated enough phantom bytes, then force a GC */ + if (gc->gen0_phantom_count > GEN0_MAX_SIZE) + collect_now(gc, 0, 0); + return 1; } @@ -4056,7 +4060,7 @@ void GC_dump_with_traces(int flags, GCWARN((GCOUTF,"Allocated (+reserved) page sizes: %" PRIdPTR " (+%" PRIdPTR ")\n", gc->used_pages * APAGE_SIZE, mmu_memory_allocated(gc->mmu) - (gc->used_pages * APAGE_SIZE))); - GCWARN((GCOUTF,"Phantom bytes: %" PRIdPTR "\n", gc->phantom_count)); + GCWARN((GCOUTF,"Phantom bytes: %" PRIdPTR "\n", (gc->phantom_count + gc->gen0_phantom_count))); GCWARN((GCOUTF,"# of major collections: %" PRIdPTR "\n", gc->num_major_collects)); GCWARN((GCOUTF,"# of minor collections: %" PRIdPTR "\n", gc->num_minor_collects)); GCWARN((GCOUTF,"# of installed finalizers: %i\n", gc->num_fnls)); @@ -4997,7 +5001,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin old_mem_use = gc->memory_in_use; old_gen0 = gc->gen0.current_size; - old_mem_allocated = mmu_memory_allocated(gc->mmu) + gc->phantom_count; + old_mem_allocated = mmu_memory_allocated(gc->mmu) + gc->phantom_count + gc->gen0_phantom_count; TIME_DECLS(); @@ -5038,6 +5042,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full) gc->phantom_count = 0; + gc->gen0_phantom_count = 0; TIME_INIT(); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 677a8927b8..a51e919a95 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -239,6 +239,7 @@ typedef struct NewGC { unsigned short phantom_tag; uintptr_t phantom_count; + uintptr_t gen0_phantom_count; Roots roots; GC_Weak_Array *weak_arrays; From c401d86bb351c93d01a3f21533d181ef298b781b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 16:35:11 -0600 Subject: [PATCH 167/381] streamline name handling in `make-struct-type` Name handling formerly interned symbols along the way to allocating a plain string, which takes effort and causes changes to the symbol table, which forces a minor GC to traverse the whole symbol table. Skip unnecessary symbol-interning steps. --- racket/src/racket/include/scheme.h | 1 + racket/src/racket/src/struct.c | 97 ++++++++++++++++++------------ 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index e2f3222f93..7170a8eb3e 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -2107,6 +2107,7 @@ extern Scheme_Extension_Table *scheme_extension_table; #define SCHEME_STRUCT_GEN_SET 0x40 #define SCHEME_STRUCT_EXPTIME 0x80 #define SCHEME_STRUCT_NO_MAKE_PREFIX 0x100 +#define SCHEME_STRUCT_NAMES_ARE_STRINGS 0x200 /*========================================================================*/ /* file descriptors */ diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index dd43c2836d..6fa00b254f 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -224,10 +224,10 @@ static Scheme_Object *make_prefab_key(Scheme_Struct_Type *type); #define BUILTIN_STRUCT_FLAGS (SCHEME_STRUCT_NO_SET | SCHEME_STRUCT_EXPTIME | SCHEME_STRUCT_NO_MAKE_PREFIX) -#define TYPE_NAME(base, blen) make_name("struct:", base, blen, "", NULL, 0, "", 1) -#define CSTR_NAME(base, blen) make_name("", base, blen, "", NULL, 0, "", 1) -#define CSTR_MAKE_NAME(base, blen) make_name("make-", base, blen, "", NULL, 0, "", 1) -#define PRED_NAME(base, blen) make_name("", base, blen, "?", NULL, 0, "", 1) +#define TYPE_NAME(base, blen, sym) make_name("struct:", base, blen, "", NULL, 0, "", sym) +#define CSTR_NAME(base, blen, sym) make_name("", base, blen, "", NULL, 0, "", sym) +#define CSTR_MAKE_NAME(base, blen, sym) make_name("make-", base, blen, "", NULL, 0, "", sym) +#define PRED_NAME(base, blen, sym) make_name("", base, blen, "?", NULL, 0, "", sym) #define GET_NAME(base, blen, field, flen, sym) make_name("", base, blen, "-", field, flen, "", sym) #define SET_NAME(base, blen, field, flen, sym) make_name("set-", base, blen, "-", field, flen, "!", sym) #define GENGET_NAME(base, blen, sym) make_name("", base, blen, "-ref", NULL, 0, "", sym) @@ -240,7 +240,7 @@ static Scheme_Object *make_prefab_key(Scheme_Struct_Type *type); static char *pred_name_string(Scheme_Object *sym) { - return scheme_symbol_val(PRED_NAME(scheme_symbol_val(sym), SCHEME_SYM_LEN(sym))); + return (char *)PRED_NAME(scheme_symbol_val(sym), SCHEME_SYM_LEN(sym), 0); } void @@ -3128,6 +3128,7 @@ static Scheme_Object *struct_type_info(int argc, Scheme_Object *argv[]) static Scheme_Object *struct_type_pred(int argc, Scheme_Object *argv[]) { Scheme_Struct_Type *stype; + char *name; check_type_and_inspector("struct-type-make-predicate", 0, argc, argv); if (SCHEME_NP_CHAPERONEP(argv[0])) @@ -3135,11 +3136,11 @@ static Scheme_Object *struct_type_pred(int argc, Scheme_Object *argv[]) else stype = (Scheme_Struct_Type *)argv[0]; - return make_struct_proc(stype, - scheme_symbol_val(PRED_NAME(scheme_symbol_val(stype->name), - SCHEME_SYM_LEN(stype->name))), - SCHEME_PRED, - stype->num_slots); + name = (char *)PRED_NAME(scheme_symbol_val(stype->name), + SCHEME_SYM_LEN(stype->name), + 0); + + return make_struct_proc(stype, name, SCHEME_PRED, stype->num_slots); } static Scheme_Object *type_constr_chaperone(Scheme_Object *o, Scheme_Object *v) @@ -3174,7 +3175,7 @@ static Scheme_Object *struct_type_constr(int argc, Scheme_Object *argv[]) stype = (Scheme_Struct_Type *)argv[0]; if ((argc < 2) || SCHEME_FALSEP(argv[1])) - v = CSTR_MAKE_NAME(scheme_symbol_val(stype->name), SCHEME_SYM_LEN(stype->name)); + v = CSTR_MAKE_NAME(scheme_symbol_val(stype->name), SCHEME_SYM_LEN(stype->name), 1); else if (SCHEME_SYMBOLP(argv[1])) v = argv[1]; else { @@ -3236,7 +3237,7 @@ Scheme_Object *scheme_struct_to_vector(Scheme_Object *_s, Scheme_Object *unknown i = stype->num_slots; last_is_unknown = 0; - name = TYPE_NAME((char *)SCHEME_STRUCT_NAME_SYM(s), -1); + name = TYPE_NAME((char *)SCHEME_STRUCT_NAME_SYM(s), -1, 1); /* Precise GC >>> BEWARE <<<, array is not GC_aligned, and is therefore marked with GC_CAN_IGNORE. */ @@ -4212,6 +4213,8 @@ Scheme_Object **scheme_make_struct_values(Scheme_Object *type, { Scheme_Struct_Type *struct_type; Scheme_Object **values; + Scheme_Object *vi; + char *nm; int slot_num, pos; struct_type = (Scheme_Struct_Type *)type; @@ -4232,18 +4235,22 @@ Scheme_Object **scheme_make_struct_values(Scheme_Object *type, if (!(flags & SCHEME_STRUCT_NO_TYPE)) values[pos++] = (Scheme_Object *)struct_type; if (!(flags & SCHEME_STRUCT_NO_CONSTR)) { - Scheme_Object *vi; + nm = ((flags & SCHEME_STRUCT_NAMES_ARE_STRINGS) + ? (char *)names[pos] + : scheme_symbol_val(names[pos])); vi = make_struct_proc(struct_type, - scheme_symbol_val(names[pos]), + nm, SCHEME_CONSTR, struct_type->num_slots); values[pos] = vi; pos++; } if (!(flags & SCHEME_STRUCT_NO_PRED)) { - Scheme_Object *vi; + nm = ((flags & SCHEME_STRUCT_NAMES_ARE_STRINGS) + ? (char *)names[pos] + : scheme_symbol_val(names[pos])); vi = make_struct_proc(struct_type, - scheme_symbol_val(names[pos]), + nm, SCHEME_PRED, 0); values[pos] = vi; @@ -4260,9 +4267,11 @@ Scheme_Object **scheme_make_struct_values(Scheme_Object *type, : 0); while (pos < count) { if (!(flags & SCHEME_STRUCT_NO_GET)) { - Scheme_Object *vi; + nm = ((flags & SCHEME_STRUCT_NAMES_ARE_STRINGS) + ? (char *)names[pos] + : scheme_symbol_val(names[pos])); vi = make_struct_proc(struct_type, - scheme_symbol_val(names[pos]), + nm, SCHEME_GETTER, slot_num); values[pos] = vi; @@ -4270,9 +4279,11 @@ Scheme_Object **scheme_make_struct_values(Scheme_Object *type, } if (!(flags & SCHEME_STRUCT_NO_SET)) { - Scheme_Object *vi; + nm = ((flags & SCHEME_STRUCT_NAMES_ARE_STRINGS) + ? (char *)names[pos] + : scheme_symbol_val(names[pos])); vi = make_struct_proc(struct_type, - scheme_symbol_val(names[pos]), + nm, SCHEME_SETTER, slot_num); values[pos] = vi; @@ -4283,18 +4294,22 @@ Scheme_Object **scheme_make_struct_values(Scheme_Object *type, } if (flags & SCHEME_STRUCT_GEN_GET) { - Scheme_Object *vi; + nm = ((flags & SCHEME_STRUCT_NAMES_ARE_STRINGS) + ? (char *)names[pos] + : scheme_symbol_val(names[pos])); vi = make_struct_proc(struct_type, - scheme_symbol_val(names[pos]), + nm, SCHEME_GEN_GETTER, slot_num); values[pos] = vi; pos++; } if (flags & SCHEME_STRUCT_GEN_SET) { - Scheme_Object *vi; + nm = ((flags & SCHEME_STRUCT_NAMES_ARE_STRINGS) + ? (char *) names[pos] + : scheme_symbol_val(names[pos])); vi = make_struct_proc(struct_type, - scheme_symbol_val(names[pos]), + nm, SCHEME_GEN_SETTER, slot_num); values[pos] = vi; @@ -4313,7 +4328,7 @@ static Scheme_Object **_make_struct_names(const char *base, int blen, Scheme_Object **names; const char *field_name; int count, fnlen; - int slot_num, pos; + int slot_num, pos, as_sym; count = 0; @@ -4350,22 +4365,24 @@ static Scheme_Object **_make_struct_names(const char *base, int blen, pos = 0; + as_sym = ((flags & SCHEME_STRUCT_NAMES_ARE_STRINGS) ? 0 : 1); + if (!(flags & SCHEME_STRUCT_NO_TYPE)) { Scheme_Object *nm; - nm = TYPE_NAME(base, blen); + nm = TYPE_NAME(base, blen, as_sym); names[pos++] = nm; } if (!(flags & SCHEME_STRUCT_NO_CONSTR)) { Scheme_Object *nm; if (flags & SCHEME_STRUCT_NO_MAKE_PREFIX) - nm = CSTR_NAME(base, blen); + nm = CSTR_NAME(base, blen, as_sym); else - nm = CSTR_MAKE_NAME(base, blen); + nm = CSTR_MAKE_NAME(base, blen, as_sym); names[pos++] = nm; } if (!(flags & SCHEME_STRUCT_NO_PRED)) { Scheme_Object *nm; - nm = PRED_NAME(base, blen); + nm = PRED_NAME(base, blen, as_sym); names[pos++] = nm; } @@ -4384,12 +4401,12 @@ static Scheme_Object **_make_struct_names(const char *base, int blen, if (!(flags & SCHEME_STRUCT_NO_GET)) { Scheme_Object *nm; - nm = GET_NAME(base, blen, field_name, fnlen, 1); + nm = GET_NAME(base, blen, field_name, fnlen, as_sym); names[pos++] = nm; } if (!(flags & SCHEME_STRUCT_NO_SET)) { Scheme_Object *nm; - nm = SET_NAME(base, blen, field_name, fnlen, 1); + nm = SET_NAME(base, blen, field_name, fnlen, as_sym); names[pos++] = nm; } } @@ -4397,18 +4414,18 @@ static Scheme_Object **_make_struct_names(const char *base, int blen, if (flags & SCHEME_STRUCT_GEN_GET) { Scheme_Object *nm; - nm = GENGET_NAME(base, blen, 1); + nm = GENGET_NAME(base, blen, as_sym); names[pos++] = nm; } if (flags & SCHEME_STRUCT_GEN_SET) { Scheme_Object *nm; - nm = GENSET_NAME(base, blen, 1); + nm = GENSET_NAME(base, blen, as_sym); names[pos++] = nm; } if (flags & SCHEME_STRUCT_EXPTIME) { Scheme_Object *nm; - nm = EXPTIME_NAME(base, blen, 1); + nm = EXPTIME_NAME(base, blen, as_sym); names[pos++] = nm; } @@ -5385,12 +5402,16 @@ static Scheme_Object *make_struct_type(int argc, Scheme_Object **argv) names = scheme_make_struct_names(argv[0], NULL, - SCHEME_STRUCT_GEN_GET | SCHEME_STRUCT_GEN_SET, + (SCHEME_STRUCT_GEN_GET | SCHEME_STRUCT_GEN_SET + | SCHEME_STRUCT_NAMES_ARE_STRINGS), &i); - if (cstr_name) - names[1] = cstr_name; + if (cstr_name) { + a = (Scheme_Object *)scheme_symbol_val(cstr_name); + names[1] = a; + } r = scheme_make_struct_values((Scheme_Object *)type, names, i, - SCHEME_STRUCT_GEN_GET | SCHEME_STRUCT_GEN_SET); + (SCHEME_STRUCT_GEN_GET | SCHEME_STRUCT_GEN_SET + | SCHEME_STRUCT_NAMES_ARE_STRINGS)); return scheme_values(i, r); } From 7eee429705653f2fca6afbe03c9aa25c3e2201af Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 19:05:09 -0600 Subject: [PATCH 168/381] avoid traversing table of JITted code names on every GC The table as a tree is traversed to prune empty branches, but the travseral is needed only toward branches that have changed. Skipping the traversal can save several milliseconds on each collection. --- racket/src/racket/src/codetab.inc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/codetab.inc b/racket/src/racket/src/codetab.inc index 77e94ef295..70438a6b4b 100644 --- a/racket/src/racket/src/codetab.inc +++ b/racket/src/racket/src/codetab.inc @@ -19,6 +19,7 @@ extern MZ_DLLIMPORT int GC_is_marked(void *); #define NODE_HEADER_SIZE 3 #define NODE_STARTS_OFFSET 1 #define NODE_GCABLE_OFFSET 2 +#define NODE_MODIFIED_OFFSET 2 /* Represent a node in the tree as an array of NODE_HEADER_SIZE + KEY_COUNT pointers. @@ -34,7 +35,10 @@ extern MZ_DLLIMPORT int GC_is_marked(void *); The third "pointer" is similar to the first, but it represents the GC status of the reference for CGC, and the bit is only used at a - range start. + range start. For precise GC, this "pointer" is used to indicate + when the array has changed and should be scanned for being + completely empty; it's ok for that flag to be approximate due to + a GC happening while arrays are being modified. Then there are KEY_COUNT "key" pointers for the content of the node. Note that KEY_COUNT is smaller than the number of bits @@ -177,6 +181,11 @@ void scheme_jit_add_symbol(uintptr_t start, uintptr_t end, void *value, int gc_a t1 = t2 = the_tree; split_t = NULL; while (offset) { +#ifdef MZ_PRECISE_GC + /* mark as modified */ + t1[NODE_MODIFIED_OFFSET] = (void *)0x1; + t2[NODE_MODIFIED_OFFSET] = (void *)0x1; +#endif offset -= LOG_KEY_SIZE; k1 = ((start >> offset) & KEY_MASK) + NODE_HEADER_SIZE; @@ -341,10 +350,16 @@ static void check_clear_symbols(void **t) void *val, **subt; #ifdef MZ_PRECISE_GC +# if 0 if (((uintptr_t *)t)[NODE_GCABLE_OFFSET] != 0x1) printf("Found GCed\n"); +# endif #endif + if (!t[NODE_MODIFIED_OFFSET]) + return; + t[NODE_MODIFIED_OFFSET] = NULL; + for (i = 0; i < KEY_COUNT; i++) { val = t[i + NODE_HEADER_SIZE]; @@ -359,7 +374,6 @@ static void check_clear_symbols(void **t) } if (j == KEY_COUNT) { t[i+NODE_HEADER_SIZE] = NULL; - // should_have_cleared(); } } } From 9372862ee2dc7992e0e398cb01a5e832e2e26601 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 19:07:17 -0600 Subject: [PATCH 169/381] GC: move minor work to clean-up phase instead of setup --- racket/src/racket/gc2/newgc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index c919286006..4acf5adf08 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4180,7 +4180,6 @@ static void mark_backpointers(NewGC *gc) mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); } work->marked_from = 1; - work->previous_size = PREFIX_SIZE; if (work->size_class) { /* must be a big page */ work->size_class = 3; @@ -4207,9 +4206,6 @@ static void mark_backpointers(NewGC *gc) work->previous_size = PREFIX_SIZE; traversed++; } else { - GCDEBUG((DEBUGOUTF,"Setting previous_size on %p to %i\n", work, - work->size)); - work->previous_size = work->size; skipped++; } } @@ -4760,6 +4756,7 @@ static void clean_up_heap(NewGC *gc) GCVERBOSEPAGE(gc, "clean_up_heap BIG PAGE ALIVE", work); work->marked_on = 0; work->marked_from = 0; + work->previous_size = work->size; memory_in_use += work->size; prev = work; } @@ -4770,6 +4767,7 @@ static void clean_up_heap(NewGC *gc) for (work = gc->gen1_pages[i]; work; work = work->next) { work->marked_on = 0; work->marked_from = 0; + work->previous_size = work->size; memory_in_use += work->size; } } From 37c4ea4720cd3b14c26c33958c30c57130b4691c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 7 Sep 2015 20:42:54 -0600 Subject: [PATCH 170/381] GC: adjust backpointer marking to not touch other page records Also, free medium pages for a terminated place. --- racket/src/racket/gc2/newgc.c | 223 ++++++++++++++++++++-------------- racket/src/racket/gc2/newgc.h | 25 ++-- 2 files changed, 145 insertions(+), 103 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 4acf5adf08..016a041799 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -1086,7 +1086,7 @@ static void *allocate_big(const size_t request_size_bytes, int type) bpage->addr = addr; bpage->size = allocate_size; - bpage->size_class = 2; + bpage->size_class = SIZE_CLASS_BIG_PAGE; bpage->page_type = type; bpage->mmu_src_block = src_block; GCVERBOSEPAGE(gc, "NEW BIG PAGE", bpage); @@ -1095,6 +1095,7 @@ static void *allocate_big(const size_t request_size_bytes, int type) bpage->next = gc->gen0.big_pages; if(bpage->next) bpage->next->prev = bpage; gc->gen0.big_pages = bpage; + gc->num_gen1_pages++; if (gc->saved_allocator) { /* MESSAGE ALLOCATION: orphan this page from the current GC; this @@ -1129,7 +1130,7 @@ inline static mpage *create_new_medium_page(NewGC *gc, const int sz, const int p page->addr = addr; page->mmu_src_block = src_block; page->size = sz; - page->size_class = 1; + page->size_class = SIZE_CLASS_MED_PAGE; page->page_type = PAGE_BIG; MED_NEXT_SEARCH_SLOT(page) = PREFIX_SIZE; page->live_size = sz; @@ -1148,6 +1149,8 @@ inline static mpage *create_new_medium_page(NewGC *gc, const int sz, const int p gc->med_pages[ty][pos] = page; gc->med_freelist_pages[ty][pos] = page; + gc->num_gen1_pages++; + if (gc->saved_allocator) { /* see MESSAGE ALLOCATION above */ orphan_page_accounting(gc, APAGE_SIZE); #ifdef POINTER_OWNERSHIP_CHECK @@ -1266,7 +1269,7 @@ inline static mpage *gen0_create_new_nursery_mpage(NewGC *gc, const size_t page_ page = malloc_mpage(); page->addr = addr; page->mmu_src_block = src_block; - page->size_class = 0; + page->size_class = SIZE_CLASS_SMALL_PAGE; page->size = PREFIX_SIZE; GEN0_ALLOC_SIZE(page) = page_size; @@ -2776,6 +2779,13 @@ inline static int page_mmu_protectable(mpage *page) { return (page->page_type == PAGE_ATOMIC) ? MMU_NON_PROTECTABLE : MMU_PROTECTABLE; } +static void set_has_back_pointers(NewGC *gc, mpage *page) +{ + page->back_pointers = 1; + page->backpointer_next = gc->backpointer_next; + gc->backpointer_next = page; +} + static int designate_modified_gc(NewGC *gc, void *p) { mpage *page = pagemap_find_page(gc->page_maps, p); @@ -2789,7 +2799,8 @@ static int designate_modified_gc(NewGC *gc, void *p) page->mprotected = 0; mmu_write_unprotect_page(gc->mmu, page->addr, real_page_size(page)); GC_MP_CNT_INC(mp_write_barrier_cnt); - page->back_pointers = 1; + if (!page->back_pointers) + set_has_back_pointers(gc, page); gc->modified_unprotects++; return 1; } else { @@ -3477,7 +3488,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) return; } /* in this case, it has not. So we want to mark it, first off. */ - page->size_class = 3; + page->size_class = SIZE_CLASS_BIG_PAGE_MARKED; /* if this is in the nursery, we want to move it out of the nursery */ if((page->generation == AGE_GEN_0) && !is_a_master_page) @@ -3599,6 +3610,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) work->next->prev = work; pagemap_add(gc->page_maps, work); gc->gen1_pages[type] = work; + gc->num_gen1_pages++; newplace = PAGE_TO_OBJHEAD(work); GCVERBOSEPAGE(gc, "NEW SMALL GEN1 PAGE", work); } @@ -4165,89 +4177,72 @@ static void reset_gen1_pages_live_and_previous_sizes(NewGC *gc) static void mark_backpointers(NewGC *gc) { + /* if this is not a full collection, then we need to mark any pointers + that point backwards into generation 0, since they're roots. */ if (!gc->gc_full) { mpage *work; - int i, ty, traversed = 0, skipped = 0; + int traversed = 0; - /* if this is not a full collection, then we need to mark any pointers - that point backwards into generation 0, since they're roots. */ - for (i = 0; i < PAGE_TYPES; i++) { - for (work = gc->gen1_pages[i]; work; work = work->next) { - if (work->back_pointers) { - if (work->mprotected) { - /* expected only if QUEUED_MPROTECT_IS_PROMISCUOUS && AGE_GEN_0_TO_GEN_HALF(gc) */ - work->mprotected = 0; - mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); - } - work->marked_from = 1; - if (work->size_class) { - /* must be a big page */ - work->size_class = 3; - push_ptr(gc, TAG_AS_BIG_PAGE_PTR(BIG_PAGE_TO_OBJECT(work))); - } else { - if (work->page_type != PAGE_ATOMIC) { - void **start = PAGE_START_VSS(work); - void **end = PAGE_END_VSS(work); + for (work = gc->backpointer_next; work; work = work->backpointer_next) { + GC_ASSERT(work->back_pointers); - while(start < end) { - objhead *info = (objhead *)start; - if (!info->dead) { - info->mark = 1; - /* This must be a push_ptr, and not a direct call to - internal_mark. This is because we need every object - in the older heap to be marked out of and noted as - marked before we do anything else */ - push_ptr(gc, OBJHEAD_TO_OBJPTR(start)); - } - start += info->size; - } - } + if (work->mprotected) { + /* expected only if QUEUED_MPROTECT_IS_PROMISCUOUS && AGE_GEN_0_TO_GEN_HALF(gc) */ + work->mprotected = 0; + mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); + } + work->marked_from = 1; + + if (work->size_class == SIZE_CLASS_BIG_PAGE) { + /* must be a big page */ + work->size_class = SIZE_CLASS_BIG_PAGE_MARKED; + push_ptr(gc, TAG_AS_BIG_PAGE_PTR(BIG_PAGE_TO_OBJECT(work))); + } else if (work->size_class == SIZE_CLASS_SMALL_PAGE) { + /* small page */ + void **start = PAGE_START_VSS(work); + void **end = PAGE_END_VSS(work); + + GC_ASSERT(work->page_type != PAGE_ATOMIC); + + while (start < end) { + objhead *info = (objhead *)start; + if (!info->dead) { + info->mark = 1; + /* This must be a push_ptr, and not a direct call to + internal_mark. This is because we need every object + in the older heap to be marked out of and noted as + marked before we do anything else */ + push_ptr(gc, OBJHEAD_TO_OBJPTR(start)); } - work->previous_size = PREFIX_SIZE; - traversed++; - } else { - skipped++; + start += info->size; + } + work->previous_size = PREFIX_SIZE; + } else { + /* medium page */ + void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); + void **end = PPTR(NUM(work->addr) + APAGE_SIZE - work->size); + + GC_ASSERT(work->size_class == SIZE_CLASS_MED_PAGE); + + while (start <= end) { + objhead *info = (objhead *)start; + if (!info->dead) { + info->mark = 1; + /* This must be a push_ptr (see above) */ + push_ptr(gc, OBJHEAD_TO_OBJPTR(info)); + } + start += info->size; } } - } - for (ty = 0; ty < MED_PAGE_TYPES; ty++) { - for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { - for (work = gc->med_pages[ty][i]; work; work = work->next) { - if (work->back_pointers) { - void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); - void **end = PPTR(NUM(work->addr) + APAGE_SIZE - work->size); - - if (work->mprotected) { - /* expected only if QUEUED_MPROTECT_IS_PROMISCUOUS && AGE_GEN_0_TO_GEN_HALF(gc) */ - work->mprotected = 0; - mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); - } - - work->marked_from = 1; - - if (ty == MED_PAGE_NONATOMIC) { - while (start <= end) { - objhead *info = (objhead *)start; - if (!info->dead) { - info->mark = 1; - /* This must be a push_ptr (see above) */ - push_ptr(gc, OBJHEAD_TO_OBJPTR(info)); - } - start += info->size; - } - } - traversed++; - } else { - skipped++; - } - } - } + traversed++; } gc->minor_old_traversed += traversed; - gc->minor_old_skipped += skipped; + gc->minor_old_skipped += (gc->num_gen1_pages - traversed); } + + gc->backpointer_next = NULL; } mpage *allocate_compact_target(NewGC *gc, mpage *work) @@ -4258,11 +4253,12 @@ mpage *allocate_compact_target(NewGC *gc, mpage *work) &npage->mmu_src_block, 1); npage->previous_size = npage->size = PREFIX_SIZE; npage->generation = AGE_GEN_1; - npage->size_class = 0; + npage->size_class = SIZE_CLASS_SMALL_PAGE; npage->page_type = work->page_type; npage->marked_on = 1; backtrace_new_page(gc, npage); pagemap_add(gc->page_maps, npage); + gc->num_gen1_pages++; GCVERBOSEPAGE(gc, "NEW COMPACT PAGE", npage); /* Link in this new replacement page */ npage->prev = work; @@ -4434,7 +4430,7 @@ static void killing_debug(NewGC *gc, mpage *page, objhead *info) { } #endif -static void repair_mixed_page(NewGC *gc, mpage *page, void **end) +static void repair_mixed_page(NewGC *gc, mpage *page, void **end, int track_back_pointers) { void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); Fixup2_Proc *fixup_table = gc->fixup_table; @@ -4501,7 +4497,12 @@ static void repair_mixed_page(NewGC *gc, mpage *page, void **end) } } - page->back_pointers = gc->back_pointers; + if (track_back_pointers) { + if (gc->back_pointers) + set_has_back_pointers(gc, page); + else + page->back_pointers = 0; + } } static void repair_heap(NewGC *gc) @@ -4523,7 +4524,7 @@ static void repair_heap(NewGC *gc) GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", page, start)); - page->size_class = 2; /* remove the mark */ + page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark */ switch(page->page_type) { case PAGE_TAGGED: fixup_table[*(unsigned short*)start](start, gc); @@ -4649,7 +4650,10 @@ static void repair_heap(NewGC *gc) } } - page->back_pointers = gc->back_pointers; + if (gc->back_pointers) + set_has_back_pointers(gc, page); + else + page->back_pointers = 0; } else GCDEBUG((DEBUGOUTF,"Not Cleaning page %p\n", page)); } } @@ -4658,14 +4662,14 @@ static void repair_heap(NewGC *gc) for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { for (page = gc->med_pages[ty][i]; page; page = page->next) { if (page->marked_on || page->marked_from) - repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size)); + repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size), 1); } } } for (page = gc->gen_half.pages; page; page = page->next) { GC_ASSERT(page->generation == AGE_GEN_HALF); - repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1)); + repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1), 0); } } @@ -4685,6 +4689,7 @@ static inline void cleanup_vacated_pages(NewGC *gc) { mpage *next = pages->next; GCVERBOSEPAGE(gc, "Cleaning up vacated", pages); gen1_free_mpage(pagemap, pages); + --gc->num_gen1_pages; pages = next; } gc->release_pages = NULL; @@ -4752,6 +4757,7 @@ static void clean_up_heap(NewGC *gc) if(next) work->next->prev = prev; GCVERBOSEPAGE(gc, "Cleaning up BIGPAGE", work); gen1_free_mpage(pagemap, work); + --gc->num_gen1_pages; } else { GCVERBOSEPAGE(gc, "clean_up_heap BIG PAGE ALIVE", work); work->marked_on = 0; @@ -4810,6 +4816,7 @@ static void clean_up_heap(NewGC *gc) if(next) work->next->prev = prev; GCVERBOSEPAGE(gc, "Cleaning up MED NO MARKEDON", work); gen1_free_mpage(pagemap, work); + --gc->num_gen1_pages; } else { /* not marked during minor gc */ memory_in_use += work->live_size; @@ -5372,7 +5379,7 @@ void GC_dump_variable_stack(void **var_stack, static void free_child_gc(void) { NewGC *gc = GC_get_GC(); - int i; + int i, ty; mpage *work; mpage *next; PageMap pagemap = gc->page_maps; @@ -5384,10 +5391,9 @@ static void free_child_gc(void) /* First, unprotect all pages. It's important to "queue" up all this work as a batch to minimize commuincation with the OS and avoid fragmenting the OS's table (in the case of Linux) that tracks page permissions. */ - for(i = 0; i < PAGE_TYPES; i++) { - if(i != PAGE_ATOMIC) { - for (work = gc->gen1_pages[i]; work; work = next) { - next = work->next; + for (i = 0; i < PAGE_TYPES; i++) { + if (i != PAGE_ATOMIC) { + for (work = gc->gen1_pages[i]; work; work = work->next) { if (work->mprotected) { work->mprotected = 0; mmu_queue_write_unprotect_range(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); @@ -5395,13 +5401,31 @@ static void free_child_gc(void) } } } + for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { + for (work = gc->med_pages[MED_PAGE_NONATOMIC][i]; work; work = work->next) { + if (work->mprotected) + mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); + } + } + mmu_flush_write_unprotect_ranges(gc->mmu); - for(i = 0; i < PAGE_TYPES; i++) { + for (i = 0; i < PAGE_TYPES; i++) { for (work = gc->gen1_pages[i]; work; work = next) { next = work->next; GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work); gen1_free_mpage(pagemap, work); + --gc->num_gen1_pages; + } + } + for (ty = 0; ty < MED_PAGE_TYPES; ty++) { + for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { + for (work = gc->med_pages[ty][i]; work; work = next) { + next = work->next; + GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work); + gen1_free_mpage(pagemap, work); + --gc->num_gen1_pages; + } } } @@ -5417,7 +5441,7 @@ static void free_child_gc(void) void GC_free_all(void) { NewGC *gc = GC_get_GC(); - int i; + int i, ty; mpage *work; mpage *next; PageMap pagemap = gc->page_maps; @@ -5428,16 +5452,27 @@ void GC_free_all(void) gen0_free_entire_nursery(gc); gen_half_free_entire_nursery(gc); - for(i = 0; i < PAGE_TYPES; i++) { + for (i = 0; i < PAGE_TYPES; i++) { for (work = gc->gen1_pages[i]; work; work = next) { next = work->next; - if (work->mprotected) - { mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); - } GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work); gen1_free_mpage(pagemap, work); + --gc->num_gen1_pages; + } + } + + for (ty = 0; ty < MED_PAGE_TYPES; ty++) { + for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { + for (work = gc->med_pages[ty][i]; work; work = next) { + next = work->next; + if (work->mprotected) + mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); + GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work); + gen1_free_mpage(pagemap, work); + --gc->num_gen1_pages; + } } } diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index a51e919a95..8b559a3924 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -13,8 +13,18 @@ typedef struct mpage { struct mpage *next; struct mpage *prev; void *addr; + void *mmu_src_block; +#ifdef MZ_GC_BACKTRACE + void **backtrace; + void *backtrace_page_src; +#endif +#ifdef MZ_USE_PLACES + uintptr_t page_lock; /* for master GC pages during marking */ +#endif uintptr_t previous_size; /* for med page, place to search for available block; for jit nursery, allocated size */ uintptr_t size; /* big page size, med page element size, or nursery starting point */ + struct mpage *backpointer_next; + unsigned short live_size; unsigned char generation :2; unsigned char back_pointers :1; unsigned char size_class :2; /* 0 => small; 1 => med; 2 => big; 3 => big marked */ @@ -23,15 +33,6 @@ typedef struct mpage { unsigned char marked_from :1; unsigned char has_new :1; unsigned char mprotected :1; - unsigned short live_size; -#ifdef MZ_GC_BACKTRACE - void **backtrace; - void *backtrace_page_src; -#endif - void *mmu_src_block; -#ifdef MZ_USE_PLACES - uintptr_t page_lock; /* for master GC pages during marking */ -#endif } mpage; typedef struct Gen0 { @@ -138,6 +139,12 @@ typedef struct NewGC { struct mpage *med_pages[MED_PAGE_TYPES][NUM_MED_PAGE_SIZES]; struct mpage *med_freelist_pages[MED_PAGE_TYPES][NUM_MED_PAGE_SIZES]; + intptr_t num_gen1_pages; + + /* linked list of pages with back pointers to be traversed in a + minor collection: */ + struct mpage *backpointer_next; + MarkSegment *mark_stack; /* Finalization */ From 8394936ee068f41a97d1412ee0e27a63811ecdcc Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 8 Sep 2015 06:23:09 -0600 Subject: [PATCH 171/381] collapse copied code in GC --- racket/src/racket/gc2/newgc.c | 47 +++++++---------------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 016a041799..71965eeeb6 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5375,10 +5375,8 @@ void GC_dump_variable_stack(void **var_stack, /* GC free all */ /******************************************************************************/ -#ifdef MZ_USE_PLACES -static void free_child_gc(void) +static void free_gc(NewGC *gc) { - NewGC *gc = GC_get_GC(); int i, ty; mpage *work; mpage *next; @@ -5434,6 +5432,13 @@ static void free_child_gc(void) mmu_flush_freed_pages(gc->mmu); mmu_free(gc->mmu); +} + +#ifdef MZ_USE_PLACES +static void free_child_gc(void) +{ + NewGC *gc = GC_get_GC(); + free_gc(gc); ofm_free(gc, sizeof(NewGC)); } #endif @@ -5441,47 +5446,13 @@ static void free_child_gc(void) void GC_free_all(void) { NewGC *gc = GC_get_GC(); - int i, ty; - mpage *work; - mpage *next; - PageMap pagemap = gc->page_maps; remove_signal_handler(gc); - gen0_free_big_pages(gc); - gen0_free_entire_nursery(gc); - gen_half_free_entire_nursery(gc); - - for (i = 0; i < PAGE_TYPES; i++) { - for (work = gc->gen1_pages[i]; work; work = next) { - next = work->next; - if (work->mprotected) - mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); - GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work); - gen1_free_mpage(pagemap, work); - --gc->num_gen1_pages; - } - } - - for (ty = 0; ty < MED_PAGE_TYPES; ty++) { - for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { - for (work = gc->med_pages[ty][i]; work; work = next) { - next = work->next; - if (work->mprotected) - mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); - GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work); - gen1_free_mpage(pagemap, work); - --gc->num_gen1_pages; - } - } - } + free_gc(gc); ofm_free(gc->mark_table, NUMBER_OF_TAGS * sizeof (Mark2_Proc)); ofm_free(gc->fixup_table, NUMBER_OF_TAGS * sizeof (Fixup2_Proc)); - free_page_maps(gc->page_maps); - free_all_stack_pages(gc); - mmu_flush_freed_pages(gc->mmu); - mmu_free(gc->mmu); ofm_free(gc, sizeof(NewGC)); } From 98b819edd428b0af723c56f3b7472abd4045ad25 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 8 Sep 2015 06:40:30 -0600 Subject: [PATCH 172/381] enable some tests Some tests that rely on a `main` submodule for places need a `test` submodule, too. --- pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt | 4 ++-- pkgs/racket-test/tests/racket/place-cross-phase.rkt | 3 +++ pkgs/racket-test/tests/racket/place-kill-unwind.rkt | 3 +++ pkgs/racket-test/tests/racket/place-struct-info.rkt | 3 +++ pkgs/racket-test/tests/racket/remote-atomic-write.rkt | 3 +++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt b/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt index b03e788d2a..fcedf299e6 100644 --- a/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt +++ b/pkgs/racket-test/tests/racket/place-chmsg-gc-acct.rkt @@ -22,5 +22,5 @@ (unless (andmap zero? r) (error "some place failed"))) - - +(module+ test + (require (submod ".." main))) diff --git a/pkgs/racket-test/tests/racket/place-cross-phase.rkt b/pkgs/racket-test/tests/racket/place-cross-phase.rkt index 7bb5c29439..594ab2fa72 100644 --- a/pkgs/racket-test/tests/racket/place-cross-phase.rkt +++ b/pkgs/racket-test/tests/racket/place-cross-phase.rkt @@ -15,3 +15,6 @@ (define p (go)) (printf "waiting\n") (place-wait p)) + +(module+ test + (require (submod ".." main))) diff --git a/pkgs/racket-test/tests/racket/place-kill-unwind.rkt b/pkgs/racket-test/tests/racket/place-kill-unwind.rkt index c06950267d..8326c2693c 100644 --- a/pkgs/racket-test/tests/racket/place-kill-unwind.rkt +++ b/pkgs/racket-test/tests/racket/place-kill-unwind.rkt @@ -24,3 +24,6 @@ (define p (go)) (place-channel-get p) (place-kill p))) + +(module+ test + (require (submod ".." main))) diff --git a/pkgs/racket-test/tests/racket/place-struct-info.rkt b/pkgs/racket-test/tests/racket/place-struct-info.rkt index fcb2fa9301..3555bb4b74 100644 --- a/pkgs/racket-test/tests/racket/place-struct-info.rkt +++ b/pkgs/racket-test/tests/racket/place-struct-info.rkt @@ -18,3 +18,6 @@ (void (place-wait (go))) (collect-garbage) (void (place-wait (go)))) + +(module+ test + (require (submod ".." main))) diff --git a/pkgs/racket-test/tests/racket/remote-atomic-write.rkt b/pkgs/racket-test/tests/racket/remote-atomic-write.rkt index 18a168c0cb..b77fd8061d 100644 --- a/pkgs/racket-test/tests/racket/remote-atomic-write.rkt +++ b/pkgs/racket-test/tests/racket/remote-atomic-write.rkt @@ -24,3 +24,6 @@ (unless (equal? 65 (place-channel-get p)) (error "crash")) 'ok) + +(module+ test + (require (submod ".." main))) From 28d5ae19f9aa6e5dd9c7fdee1e6c18780f8b694d Mon Sep 17 00:00:00 2001 From: John Clements Date: Wed, 2 Sep 2015 14:31:22 -0700 Subject: [PATCH 173/381] http-client: don't try to gunzip an empty stream --- racket/collects/net/http-client.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/racket/collects/net/http-client.rkt b/racket/collects/net/http-client.rkt index 6e254c44eb..f74553bb11 100644 --- a/racket/collects/net/http-client.rkt +++ b/racket/collects/net/http-client.rkt @@ -261,7 +261,9 @@ (define decoded-response-port (cond [head? raw-response-port] - [(and (memq 'gzip decodes) (regexp-member #rx#"^(?i:Content-Encoding: +gzip)$" headers)) + [(and (memq 'gzip decodes) + (regexp-member #rx#"^(?i:Content-Encoding: +gzip)$" headers) + (not (eof-object? (peek-byte raw-response-port)))) (define-values (in out) (make-pipe PIPE-SIZE)) (define gunzip-t (thread From 98a861507fc37e429013579097c8dcfbb8e24d9c Mon Sep 17 00:00:00 2001 From: John Clements Date: Thu, 3 Sep 2015 09:07:05 -0700 Subject: [PATCH 174/381] net: make # structure transparent --- racket/collects/net/url-structs.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/net/url-structs.rkt b/racket/collects/net/url-structs.rkt index ee6177c11f..87e1c4bc3d 100644 --- a/racket/collects/net/url-structs.rkt +++ b/racket/collects/net/url-structs.rkt @@ -3,7 +3,8 @@ (define-serializable-struct url (scheme user host port path-absolute? path query fragment) - #:mutable) + #:mutable + #:transparent) (define-serializable-struct path/param (path param)) (provide/contract From a07ed4647e2f3b1b6de0eda633059c413eb40a09 Mon Sep 17 00:00:00 2001 From: John Clements Date: Fri, 4 Sep 2015 08:49:29 -0700 Subject: [PATCH 175/381] make path/param transparent --- racket/collects/net/url-structs.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/net/url-structs.rkt b/racket/collects/net/url-structs.rkt index 87e1c4bc3d..c6736e3835 100644 --- a/racket/collects/net/url-structs.rkt +++ b/racket/collects/net/url-structs.rkt @@ -5,7 +5,8 @@ (scheme user host port path-absolute? path query fragment) #:mutable #:transparent) -(define-serializable-struct path/param (path param)) +(define-serializable-struct path/param (path param) + #:transparent) (provide/contract (struct url ([scheme (or/c false/c string?)] From 33bb5e906086e4e0c0951d840916f8fa4bef602c Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 7 Sep 2015 20:25:34 -0400 Subject: [PATCH 176/381] Make prop:rename-transformer accept a procedure Allows the choice of target identifier to be delayed until expansion time, rather than fixed at the point of the transformer definition. --- .../scribblings/reference/stx-trans.scrbl | 35 +++++++- pkgs/racket-test-core/tests/racket/stx.rktl | 82 +++++++++++++++++++ racket/src/racket/src/struct.c | 22 ++++- 3 files changed, 133 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index 44278cc3a9..7548b0d335 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -181,8 +181,9 @@ A @tech{structure type property} to identify structure types that act as @tech{rename transformers} like the ones created by @racket[make-rename-transformer]. -The property value must be an exact integer or an identifier -@tech{syntax object}. In the former case, the integer designates a +The property value must be an exact integer, an identifier +@tech{syntax object}, or a procedure that takes one argument. +In the former case, the integer designates a field within the structure that should contain an identifier; the integer must be between @racket[0] (inclusive) and the number of non-automatic fields in the structure type (exclusive, not counting @@ -194,7 +195,35 @@ target for renaming, just like the first argument to @racket[make-rename-transformer]. If the property value is an integer, the target identifier is extracted from the structure instance; if the field value is not an identifier, then an identifier @racketidfont{?} -with an empty context is used, instead.} +with an empty context is used, instead. + +If the property value is a procedure that takes one argument, then the procedure +is called to obtain the identifier that the rename transformer will use +as a target identifier. If the procedure returns any value that is not +an identifier, the @racket[exn:fail:contract] exception is raised. + +@examples[#:eval stx-eval #:escape UNSYNTAX + (code:comment "Example of a procedure argument for prop:rename-transformer") + (define-syntax slv-1 'first-transformer-binding) + (define-syntax slv-2 'second-transformer-binding) + (begin-for-syntax + (struct slv-cooperator (redirect-to-first?) + #:property prop:rename-transformer + (λ (inst) + (if (slv-cooperator-redirect-to-first? inst) + #'slv-1 + #'slv-2)))) + (define-syntax (slv-lookup stx) + (syntax-case stx () + [(_ id) + #`(quote #,(syntax-local-value #'id))])) + (define-syntax slv-inst-1 (slv-cooperator #t)) + (define-syntax slv-inst-2 (slv-cooperator #f)) + (slv-lookup slv-inst-1) + (slv-lookup slv-inst-2) +] + +@history[#:changed "6.3" "the property now accepts a procedure of one argument."]} @defproc[(local-expand [stx any/c] diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 7a5abe1e3c..93bef70763 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -2105,6 +2105,88 @@ (check stx #f) (check #f a-stx)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Test prop:rename-transformer with procedure content + +(begin-for-syntax + (struct slv-struct-1 (id) + #:property prop:rename-transformer + (λ (o) (slv-struct-1-id o))) + + (struct slv-struct-2 (t1? t1 t2) + #:property prop:rename-transformer + (λ (o) + (if (slv-struct-2-t1? o) + (slv-struct-2-t1 o) + (slv-struct-2-t2 o)))) + + (struct slv-struct-bad () + #:property prop:rename-transformer + (λ (o) 'not-an-identifier))) + +(let () + (define-syntax target-1 't1) + (define-syntax target-2 't2) + + (define-syntax (m stx) + (syntax-case stx () + [(_ id) + #`(quote #,(syntax-local-value #'id) )])) + + (define-syntax (m2 stx) + (syntax-case stx () + [(_ id) + (let-values ([(x y) (syntax-local-value/immediate #'id)]) + #`(list (quote #,(if (rename-transformer? x) 'rename-transformer x)) + (quote #,(and y (syntax-e y)))))])) + + (define-syntax s1 (slv-struct-1 #'target-1)) + (define-syntax s2 (slv-struct-1 #'target-2)) + (define-syntax s3 (make-rename-transformer #'target-2)) + (define-syntax s4 (slv-struct-1 #'s3)) + (define-syntax s5 (slv-struct-2 #t #'target-1 #'target-2)) + (define-syntax s6 (slv-struct-2 #f #'target-1 #'target-2)) + (define-syntax s7 (slv-struct-2 #t #'s3 #'target-2)) + (define-syntax s8 (slv-struct-2 #f #'s3 #'target-2)) + (define-syntax s9 (make-rename-transformer #'s8)) + + (test 't1 values (m s1)) + (test '(rename-transformer target-1) values (m2 s1)) + (test 't2 values (m s2)) + (test '(rename-transformer target-2) values (m2 s2)) + (test 't2 values (m s4)) + (test '(rename-transformer s3) values (m2 s4)) + (test 't1 values (m s5)) + (test '(rename-transformer target-1) values (m2 s5)) + (test 't2 values (m s6)) + (test '(rename-transformer target-2) values (m2 s6)) + (test 't2 values (m s7)) + (test '(rename-transformer s3) values (m2 s7)) + (test 't2 values (m s8)) + (test '(rename-transformer target-2) values (m2 s8)) + (test 't2 values (m s9)) + (test '(rename-transformer s8) values (m2 s9)) + + (define target-3 't3) + (define target-4 't4) + (define-syntax r1 (slv-struct-1 #'target-3)) + (define-syntax r2 (slv-struct-1 #'target-4)) + (define-syntax r3 (slv-struct-2 #t #'target-3 #'target-4)) + (define-syntax r4 (slv-struct-2 #f #'target-3 #'target-4)) + (test 't3 values r1) + (test 't4 values r2) + (test 't3 values r3) + (test 't4 values r4) + + (err/rt-test + (let () + (struct foo () #:property prop:rename-transformer (λ (x y) 3)) + (void)) + exn:fail:contract?) + (err/rt-test + (eval #'(let () (define-syntax s-bad (slv-struct-bad)) (m s-bad))) + exn:fail:contract?)) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index 6fa00b254f..353885cbc1 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -1882,14 +1882,30 @@ int scheme_is_binding_rename_transformer(Scheme_Object *o) static int is_stx_id(Scheme_Object *o) { return (SCHEME_STXP(o) && SCHEME_SYMBOLP(SCHEME_STX_VAL(o))); } +static int is_stx_id_or_proc_1(Scheme_Object *o) { return (is_stx_id(o) || is_proc_1(o)); } + Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o) { + Scheme_Object *a[1]; + if (SAME_TYPE(SCHEME_TYPE(o), scheme_id_macro_type)) return SCHEME_PTR1_VAL(o); if (SCHEME_CHAPERONE_STRUCTP(o)) { Scheme_Object *v; v = scheme_struct_type_property_ref(rename_transformer_property, o); - if (SCHEME_INTP(v)) { + if (SCHEME_PROCP(v)) { + a[0] = o; + /* apply a continuation barrier here to prevent a capture in + * the property access */ + v = scheme_apply(v, 1, a); + if (!is_stx_id(v)) { + scheme_contract_error("prop:rename-transformer", + "contract violation for given value", + "expected", 0, "identifier?", + "given", 1, v, + NULL); + } + } else if (SCHEME_INTP(v)) { v = scheme_struct_ref(o, SCHEME_INT_VAL(v)); if (!is_stx_id(v)) { v = scheme_datum_to_syntax(scheme_intern_symbol("?"), scheme_false, scheme_false, 0, 0); @@ -1903,8 +1919,8 @@ Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o) static Scheme_Object *check_rename_transformer_property_value_ok(int argc, Scheme_Object *argv[]) { return check_indirect_property_value_ok("guard-for-prop:rename-transformer", - is_stx_id, 0, - "(or/c exact-nonnegative-integer? identifier?)", + is_stx_id_or_proc_1, 0, + "(or/c exact-nonnegative-integer? identifier? (-> any/c identifier?))", argc, argv); } From 261b7bde28b8c46191a7fb7ad83cec10ccd5135d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 8 Sep 2015 15:27:46 -0600 Subject: [PATCH 177/381] set-phantom-bytes!: fix tracking across generations --- racket/src/racket/gc2/gc2.h | 4 ++-- racket/src/racket/gc2/newgc.c | 15 ++++++++++++--- racket/src/racket/src/thread.c | 4 ++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index 84e6cfb3a9..307ab2c48c 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -277,10 +277,10 @@ GC2_EXTERN int GC_is_on_allocated_page(void *p); the GC allocates objects (although p may or may not be a valid pointer to the start of an alloctaed object). */ -GC2_EXTERN int GC_allocate_phantom_bytes(intptr_t); +GC2_EXTERN int GC_allocate_phantom_bytes(void *pb, intptr_t); /* Returns 0 if allocation should fail due to a memory limit, - 1 otherwise. */ + 1 otherwise. The representative `pb` determines who is charged. */ /***************************************************************************/ /* Memory tracing */ diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 71965eeeb6..ba710c56c9 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -1656,9 +1656,10 @@ uintptr_t add_no_overflow(uintptr_t a, uintptr_t b) return c; } -int GC_allocate_phantom_bytes(intptr_t request_size_bytes) +int GC_allocate_phantom_bytes(void *pb, intptr_t request_size_bytes) { NewGC *gc = GC_get_GC(); + mpage *page; #ifdef NEWGC_BTC_ACCOUNT if (request_size_bytes > 0) { @@ -1674,14 +1675,22 @@ int GC_allocate_phantom_bytes(intptr_t request_size_bytes) /* overflow */ return 1; - gc->gen0_phantom_count += request_size_bytes; + page = pagemap_find_page(gc->page_maps, pb); + /* adjust `gc->memory_in_use', but protect against {over,under}flow: */ if (request_size_bytes < 0) { request_size_bytes = -request_size_bytes; if (gc->memory_in_use > request_size_bytes) gc->memory_in_use -= request_size_bytes; - } else + if (!page || (page->generation != AGE_GEN_1)) { + if (gc->gen0_phantom_count > request_size_bytes) + gc->gen0_phantom_count -= request_size_bytes; + } + } else { + if (!page || (page->generation != AGE_GEN_1)) + gc->gen0_phantom_count = add_no_overflow(gc->gen0_phantom_count, request_size_bytes); gc->memory_in_use = add_no_overflow(gc->memory_in_use, request_size_bytes); + } /* If we've allocated enough phantom bytes, then force a GC */ if (gc->gen0_phantom_count > GEN0_MAX_SIZE) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 7f47807b87..7ef4c0db43 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -8309,7 +8309,7 @@ static Scheme_Object *make_phantom_bytes(int argc, Scheme_Object *argv[]) pb->size = SCHEME_INT_VAL(argv[0]); # ifdef MZ_PRECISE_GC - if (!GC_allocate_phantom_bytes(pb->size)) + if (!GC_allocate_phantom_bytes(pb, pb->size)) scheme_raise_out_of_memory("make-phantom-bytes", NULL); # endif @@ -8330,7 +8330,7 @@ static Scheme_Object *set_phantom_bytes(int argc, Scheme_Object *argv[]) amt = SCHEME_INT_VAL(argv[1]); # ifdef MZ_PRECISE_GC - if (!GC_allocate_phantom_bytes(amt - pb->size)) + if (!GC_allocate_phantom_bytes(pb, amt - pb->size)) scheme_raise_out_of_memory("make-phantom-bytes", NULL); # endif From 5f43b3a91323997e7c7a3cca4188d711dd26a64c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 8 Sep 2015 10:09:29 -0500 Subject: [PATCH 178/381] Move `non-empty-string?` to `racket/string`. From `unstable/contract`. --- pkgs/racket-doc/scribblings/reference/strings.scrbl | 7 +++++++ racket/collects/racket/string.rkt | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/strings.scrbl b/pkgs/racket-doc/scribblings/reference/strings.scrbl index df7055db72..6b16f7c236 100644 --- a/pkgs/racket-doc/scribblings/reference/strings.scrbl +++ b/pkgs/racket-doc/scribblings/reference/strings.scrbl @@ -507,6 +507,13 @@ trimmed (which is an alternative to using a @tech{regular expression} (string-trim "aaaxaayaa" "aa") ]} +@defproc[(non-empty-string? [x any/c]) boolean?]{ +Returns @racket[#t] if @racket[x] is a string and is not empty; +returns @racket[#f] otherwise. +@history[#:added "6.2.900.15"]{} +} + + @; ---------------------------------------- @include-section["format.scrbl"] diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index 29e3e57367..6e8ad8d18b 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -5,7 +5,8 @@ string-trim string-normalize-spaces string-split - string-replace) + string-replace + non-empty-string?) (define string-append* (case-lambda [(strs) (apply string-append strs)] ; optimize common cases @@ -134,3 +135,6 @@ (if all? (regexp-replace* from* str to*) (regexp-replace from* str to*))) + +(define (non-empty-string? x) + (and (string? x) (not (zero? (string-length x))))) From dc11eede98d395200ad338a6513ff393266bdd83 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 8 Sep 2015 11:04:23 -0500 Subject: [PATCH 179/381] Add links to docs. --- pkgs/racket-doc/scribblings/reference/format.scrbl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/format.scrbl b/pkgs/racket-doc/scribblings/reference/format.scrbl index 13761200e6..7a240c8307 100644 --- a/pkgs/racket-doc/scribblings/reference/format.scrbl +++ b/pkgs/racket-doc/scribblings/reference/format.scrbl @@ -5,7 +5,8 @@ "mz.rkt" (for-label racket/contract racket/math - racket/format)) + racket/format + racket/string)) @(begin (define the-eval (make-base-eval)) From 147baa63f7897116647dac25ea86f39174b6ed5e Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 8 Sep 2015 11:22:33 -0500 Subject: [PATCH 180/381] Add `port-number?` and `listen-port-number?` to `racket/tcp`. From `unstable/contract`. --- .../scribblings/reference/networking.scrbl | 47 +++++++++++-------- racket/collects/racket/tcp.rkt | 17 ++++++- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/networking.scrbl b/pkgs/racket-doc/scribblings/reference/networking.scrbl index 33d25571f0..2fb05d19b2 100644 --- a/pkgs/racket-doc/scribblings/reference/networking.scrbl +++ b/pkgs/racket-doc/scribblings/reference/networking.scrbl @@ -13,7 +13,7 @@ For information about TCP in general, see @italic{TCP/IP Illustrated, Volume 1} by W. Richard Stevens. -@defproc[(tcp-listen [port-no (integer-in 0 65535)] +@defproc[(tcp-listen [port-no listen-port-number?] [max-allow-wait exact-nonnegative-integer? 4] [reuse? any/c #f] [hostname (or/c string? #f) #f]) @@ -67,9 +67,9 @@ A TCP listener is @tech{ready for synchronization} when @defproc[(tcp-connect [hostname string?] - [port-no (integer-in 1 65535)] + [port-no port-number?] [local-hostname (or/c string? #f) #f] - [local-port-no (or/c (integer-in 1 65535) #f) + [local-port-no (or/c port-number? #f) #f]) (values input-port? output-port?)]{ @@ -121,9 +121,9 @@ If a connection cannot be established by @racket[tcp-connect], the @exnraise[exn:fail:network].} @defproc[(tcp-connect/enable-break [hostname string?] - [port-no (integer-in 1 65535)] + [port-no port-number?] [local-hostname (or/c string? #f) #f] - [local-port-no (or/c (integer-in 1 65535) #f)]) + [local-port-no (or/c port-number? #f)]) (values input-port? output-port?)]{ Like @racket[tcp-connect], but breaking is enabled (see @@ -224,8 +224,8 @@ connections, so @racket[tcp-abandon-port] is equivalent to @defproc[(tcp-addresses [tcp-port (or/c tcp-port? tcp-listener?)] [port-numbers? any/c #f]) (or/c (values string? string?) - (values string? (integer-in 1 65535) - string? (integer-in 0 65535)))]{ + (values string? port-number? + string? listen-port-number?))]{ Returns two strings when @racket[port-numbers?] is @racket[#f] (the default). The first string is the Internet address for the local @@ -255,6 +255,14 @@ port returned by @racket[tcp-accept], @racket[tcp-connect], @racket[tcp-accept/enable-break], or @racket[tcp-connect/enable-break]---@racket[#f] otherwise.} +@defthing[port-number? contract?]{ +Equivalent to @racket[(between/c 1 65535)]. +} + +@defthing[listen-port-number? contract?]{ +Equivalent to @racket[(between/c 0 65535)]. +} + @;------------------------------------------------------------------------ @section[#:tag "udp"]{UDP} @@ -264,7 +272,7 @@ For information about UDP in general, see @italic{TCP/IP Illustrated, Volume 1} by W. Richard Stevens. @defproc[(udp-open-socket [family-hostname (or/c string? #f) #f] - [family-port-no (or/c (integer-in 1 65535) #f) #f]) + [family-port-no (or/c port-number? #f) #f]) udp?]{ Creates and returns a @deftech{UDP socket} to send and receive @@ -285,7 +293,7 @@ non-@racket[#f], then the socket's protocol family is IPv4.} @defproc[(udp-bind! [udp-socket udp?] [hostname-string (or/c string? #f)] - [port-no (integer-in 0 65535)] + [port-no listen-port-number?] [reuse? any/c #f]) void?]{ @@ -327,8 +335,7 @@ machine when using UDP multicast.} @defproc[(udp-connect! [udp-socket udp?] [hostname-string (or/c string? #f)] - [port-no (or/c (integer-in 1 65535) - #f)]) + [port-no (or/c port-number? #f)]) void?]{ Connects the socket to the indicated remote address and port if @@ -351,7 +358,7 @@ If @racket[udp-socket] is closed, the @exnraise[exn:fail:network].} @defproc[(udp-send-to [udp-socket udp?] [hostname string?] - [port-no (integer-in 1 65535)] + [port-no port-number?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) @@ -385,7 +392,7 @@ connected, and the datagram goes to the connection target. If @defproc[(udp-send-to* [udp-socket udp?] [hostname string?] - [port-no (integer-in 1 65535)] + [port-no port-number?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) @@ -406,7 +413,7 @@ never blocks and returns @racket[#f] or @racket[#t].} @defproc[(udp-send-to/enable-break [udp-socket udp?] [hostname string?] - [port-no (integer-in 1 65535)] + [port-no port-number?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) @@ -435,7 +442,7 @@ Like @racket[udp-send], except that breaks are enabled like [end-pos exact-nonnegative-integer? (bytes-length bstr)]) (values exact-nonnegative-integer? string? - (integer-in 1 65535))]{ + port-number?)]{ Accepts up to @math{@racket[end-pos]-@racket[start-pos]} bytes of @racket[udp-socket]'s next incoming datagram into @racket[bstr], @@ -462,7 +469,7 @@ the length of @racket[bstr], the @exnraise[exn:fail:contract].} [end-pos exact-nonnegative-integer? (bytes-length bstr)]) (values (or/c exact-nonnegative-integer? #f) (or/c string? #f) - (or/c (integer-in 1 65535) #f))]{ + (or/c port-number? #f))]{ Like @racket[udp-receive!], except that it never blocks. If no datagram is available, the three result values are all @racket[#f].} @@ -473,7 +480,7 @@ datagram is available, the three result values are all @racket[#f].} [end-pos exact-nonnegative-integer? (bytes-length bstr)]) (values exact-nonnegative-integer? string? - (integer-in 1 65535))]{ + port-number?)]{ Like @racket[udp-receive!], but breaking is enabled (see @secref["breakhandler"]) while trying to receive the datagram. If @@ -523,7 +530,7 @@ would block. The @tech{synchronization result} is the event itself. @defproc[(udp-send-to-evt [udp-socket udp?] [hostname string?] - [port-no (integer-in 1 65535)] + [port-no port-number?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) @@ -570,8 +577,8 @@ content is not modified if the event is not chosen.)} @defproc[(udp-addresses [udp-port udp?] [port-numbers? any/c #f]) (or/c (values string? string?) - (values string? (integer-in 0 65535) - string? (integer-in 0 65535)))]{ + (values string? listen-port-number? + string? listen-port-number?))]{ Returns two strings when @racket[port-numbers?] is @racket[#f] (the default). The first string is the Internet address for the local diff --git a/racket/collects/racket/tcp.rkt b/racket/collects/racket/tcp.rkt index 92d18f3216..51149afc01 100644 --- a/racket/collects/racket/tcp.rkt +++ b/racket/collects/racket/tcp.rkt @@ -14,7 +14,9 @@ tcp-listener? tcp-addresses tcp-abandon-port - tcp-port?) + tcp-port? + port-number? + listen-port-number?) (define-values (tcp-addresses) (case-lambda @@ -26,6 +28,19 @@ (c:tcp-addresses socket port-numbers?) (raise-argument-error 'tcp-addresses "(or/c tcp-port? tcp-listener?)" socket)))])) + (define-values (port-number?) + (lambda (x) (if (exact-integer? x) + (if (>= x 1) + (<= x 65535) + #f) + #f))) + (define-values (listen-port-number?) + (lambda (x) (if (exact-integer? x) + (if (>= x 0) + (<= x 65535) + #f) + #f))) + ;; Because we can, and because it makes a good test: (#%declare #:cross-phase-persistent)) From e358c49573cb986c708f86afaa0d091b407beffa Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 8 Sep 2015 14:27:59 -0500 Subject: [PATCH 181/381] Add `rename-contract`, `if/c` and `failure-result/c` from unstable/contract. --- .../scribblings/reference/contracts.scrbl | 47 ++++++++++++++ racket/collects/racket/contract/base.rkt | 12 +++- .../collects/racket/contract/private/misc.rkt | 64 ++++++++++++++++++- 3 files changed, 121 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 0ba6295bd7..5b386ce3be 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -2819,6 +2819,53 @@ currently being checked. @history[#:added "6.1.1.5"] } +@defproc[(rename-contract [contract contract?] + [name any/c]) + contract?]{ + Produces a contract that acts like @racket[contract] but with the name + @racket[name]. + + The resulting contract is a flat contract if @racket[contract] is a + flat contract. + + @history[#:added "6.2.900.15"] +} + +@defproc[(if/c [predicate (-> any/c any/c)] + [then-contract contract?] + [else-contract contract?]) + contract?]{ + Produces a contract that, when applied to a value, first tests the + value with @racket[predicate]; if @racket[predicate] returns true, the + @racket[then-contract] is applied; otherwise, the + @racket[else-contract] is applied. The resulting contract is a flat + contract if both @racket[then-contract] and @racket[else-contract] are + flat contracts. + + For example, the following contract enforces that if a value is a + procedure, it is a thunk; otherwise it can be any (non-procedure) + value: + @racketblock[(if/c procedure? (-> any) any/c)] + Note that the following contract is @bold{not} equivalent: + @racketblock[(or/c (-> any) any/c) (code:comment "wrong!")] + The last contract is the same as @racket[any/c] because + @racket[or/c] tries flat contracts before higher-order contracts. + + @history[#:added "6.2.900.15"] +} + +@defthing[failure-result/c contract?]{ + A contract that describes the failure result arguments of procedures + such as @racket[hash-ref]. + + Equivalent to @racket[(if/c procedure? (-> any) any/c)]. + + @history[#:added "6.2.900.15"] +} + + + + @section{@racketmodname[racket/contract/base]} @defmodule[racket/contract/base] diff --git a/racket/collects/racket/contract/base.rkt b/racket/collects/racket/contract/base.rkt index 8ec36b86b8..857b341d67 100644 --- a/racket/collects/racket/contract/base.rkt +++ b/racket/collects/racket/contract/base.rkt @@ -68,4 +68,14 @@ list-contract? ;; from private/case-arrow.rkt - case->) + case-> + + ;; from here (needs `->`, so can't be deeper) + failure-result/c) + +;; failure-result/c : contract +;; Describes the optional failure argument passed to hash-ref, for example. +;; If the argument is a procedure, it must be a thunk, and it is applied. Otherwise +;; the argument is simply the value to return. +(define failure-result/c + (if/c procedure? (-> any) any/c)) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index b65f3756b0..2adcd4cedb 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -64,7 +64,10 @@ blame-add-cdr-context raise-not-cons-blame-error - random-any/c) + random-any/c + + rename-contract + if/c) (define-syntax (flat-murec-contract stx) (syntax-case stx () @@ -2155,3 +2158,62 @@ (listof any/c) (cons/c any/c any/c) (list/c)) + +;; rename-contract : contract any/c -> contract +;; If the argument is a flat contract, so is the result. +(define (rename-contract ctc name) + (unless (contract? ctc) + (raise-type-error 'rename-contract "contract?" ctc)) + (let ([ctc (coerce-contract 'rename-contract ctc)]) + (if (flat-contract? ctc) + (flat-named-contract name (flat-contract-predicate ctc)) + (let* ([make-contract (if (chaperone-contract? ctc) make-chaperone-contract make-contract)]) + (define (stronger? this other) + (contract-stronger? ctc other)) + (make-contract #:name name + #:projection (contract-projection ctc) + #:first-order (contract-first-order ctc) + #:stronger stronger? + #:list-contract? (list-contract? ctc)))))) + +;; (if/c predicate then/c else/c) applies then/c to satisfying +;; predicate, else/c to those that don't. +(define (if/c predicate then/c else/c) + #| + Naive version: + (or/c (and/c predicate then/c) + (and/c (not/c predicate) else/c)) + But that applies predicate twice. + |# + (unless (procedure? predicate) + (raise-type-error 'if/c "procedure?" predicate)) + (unless (contract? then/c) + (raise-type-error 'if/c "contract?" then/c)) + (unless (contract? else/c) + (raise-type-error 'if/c "contract?" else/c)) + (let ([then-ctc (coerce-contract 'if/c then/c)] + [else-ctc (coerce-contract 'if/c else/c)]) + (define name (build-compound-type-name 'if/c predicate then-ctc else-ctc)) + ;; Special case: if both flat contracts, make a flat contract. + (if (and (flat-contract? then-ctc) + (flat-contract? else-ctc)) + ;; flat contract + (let ([then-pred (flat-contract-predicate then-ctc)] + [else-pred (flat-contract-predicate else-ctc)]) + (define (pred x) + (if (predicate x) (then-pred x) (else-pred x))) + (flat-named-contract name pred)) + ;; ho contract + (let ([then-proj (contract-projection then-ctc)] + [then-fo (contract-first-order then-ctc)] + [else-proj (contract-projection else-ctc)] + [else-fo (contract-first-order else-ctc)]) + (define ((proj blame) x) + (if (predicate x) + ((then-proj blame) x) + ((else-proj blame) x))) + (make-contract + #:name name + #:projection proj + #:first-order + (lambda (x) (if (predicate x) (then-fo x) (else-fo x)))))))) From 965fa8e34c56d465b21adfd3e3ce3e9efb273267 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 8 Sep 2015 14:57:47 -0500 Subject: [PATCH 182/381] Start using `failure-result/c` in docs. Not exhaustive, just what I could think of. --- pkgs/racket-doc/scribblings/reference/dicts.scrbl | 9 ++++++--- .../racket-doc/scribblings/reference/hashes.scrbl | 15 +++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/dicts.scrbl b/pkgs/racket-doc/scribblings/reference/dicts.scrbl index 692a08a141..121b58acad 100644 --- a/pkgs/racket-doc/scribblings/reference/dicts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/dicts.scrbl @@ -180,7 +180,8 @@ only supported for dictionary types that directly implement them. @defproc[(dict-ref [dict dict?] [key any/c] - [failure-result any/c (lambda () (raise (make-exn:fail ....)))]) + [failure-result (failure-result/c any/c) + (lambda () (raise (make-exn:fail ....)))]) any]{ Returns the value for @racket[key] in @racket[dict]. If no value @@ -471,7 +472,8 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and @defproc[(dict-update! [dict (and/c dict? (not/c immutable?))] [key any/c] [updater (any/c . -> . any/c)] - [failure-result any/c (lambda () (raise (make-exn:fail ....)))]) void?]{ + [failure-result (failure-result/c any/c) + (lambda () (raise (make-exn:fail ....)))]) void?]{ Composes @racket[dict-ref] and @racket[dict-set!] to update an existing mapping in @racket[dict], where the optional @racket[failure-result] @@ -496,7 +498,8 @@ v @defproc[(dict-update [dict dict?] [key any/c] [updater (any/c . -> . any/c)] - [failure-result any/c (lambda () (raise (make-exn:fail ....)))]) + [failure-result (failure-result/c any/c) + (lambda () (raise (make-exn:fail ....)))]) (and/c dict? immutable?)]{ Composes @racket[dict-ref] and @racket[dict-set] to functionally diff --git a/pkgs/racket-doc/scribblings/reference/hashes.scrbl b/pkgs/racket-doc/scribblings/reference/hashes.scrbl index bd41fff249..1677bd9a43 100644 --- a/pkgs/racket-doc/scribblings/reference/hashes.scrbl +++ b/pkgs/racket-doc/scribblings/reference/hashes.scrbl @@ -235,8 +235,9 @@ later mappings overwrite earlier mappings. @defproc[(hash-ref [hash hash?] [key any/c] - [failure-result any/c (lambda () - (raise (make-exn:fail:contract ....)))]) + [failure-result (failure-result/c any/c) + (lambda () + (raise (make-exn:fail:contract ....)))]) any]{ Returns the value for @racket[key] in @racket[hash]. If no value @@ -277,8 +278,9 @@ Returns @racket[#t] if @racket[hash] contains a value for the given @defproc[(hash-update! [hash (and/c hash? (not/c immutable?))] [key any/c] [updater (any/c . -> . any/c)] - [failure-result any/c (lambda () - (raise (make-exn:fail:contract ....)))]) + [failure-result (failure-result/c any/c) + (lambda () + (raise (make-exn:fail:contract ....)))]) void?]{ Composes @racket[hash-ref] and @racket[hash-set!] to update an @@ -293,8 +295,9 @@ concurrent updates. @defproc[(hash-update [hash (and/c hash? immutable?)] [key any/c] [updater (any/c . -> . any/c)] - [failure-result any/c (lambda () - (raise (make-exn:fail:contract ....)))]) + [failure-result (failure-result/c any/c) + (lambda () + (raise (make-exn:fail:contract ....)))]) (and/c hash? immutable?)]{ Composes @racket[hash-ref] and @racket[hash-set] to functionally From 707f888c83810bff6450fbf3d416a18802e0f57e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 8 Sep 2015 16:47:24 -0600 Subject: [PATCH 183/381] make base: more complete avoidance of user-specific state User-scope package installation matching the version of Racket being built could affect the collections visible during `raco setup` for `make base`. In particular, the presence of `setup/scribble` could cause all built docs to be discarded. Also, add the `--no-user-path` flag to `racket` (which has long been documented as an alias for `-U`). --- racket/collects/setup/setup-core.rkt | 3 ++- racket/src/Makefile.in | 4 +++- racket/src/configure | 4 ++++ racket/src/racket/cmdline.inc | 2 ++ racket/src/racket/configure.ac | 3 +++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index 909f2707a6..ac28c34d29 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -1922,7 +1922,8 @@ (setup-printf "links files" "") (for ([p (get-links-search-files)]) (setup-printf #f " ~a" p)) - (setup-printf #f " ~a" (find-user-links-file)) + (when (use-user-specific-search-paths) + (setup-printf #f " ~a" (find-user-links-file))) (setup-printf "main docs" "~a" (find-doc-dir)) (when (and (not (null? (archives))) no-specific-collections?) diff --git a/racket/src/Makefile.in b/racket/src/Makefile.in index af98447690..51e0b4660b 100644 --- a/racket/src/Makefile.in +++ b/racket/src/Makefile.in @@ -80,7 +80,9 @@ both: # Install (common) ---------------------------------------- INST_CONFIG = -X @DIRCVTPRE@"$(DESTDIR)$(collectsdir)"@DIRCVTPOST@ -G @DIRCVTPRE@"$(DESTDIR)$(configdir)"@DIRCVTPOST@ -SETUP_ARGS = $(INST_CONFIG) $(SELF_RACKET_FLAGS) -N "raco" -l- setup @INSTALL_SETUP_FLAGS@ $(PLT_SETUP_OPTIONS) $(PLT_ISO) +SETUP_RACKET_FLAGS = $(INST_CONFIG) $(SELF_RACKET_FLAGS) @INSTALL_SETUP_RACKET_FLAGS@ +SETUP_SETUP_FLAGS = @INSTALL_SETUP_FLAGS@ $(PLT_SETUP_OPTIONS) $(PLT_ISO) +SETUP_ARGS = $(SETUP_RACKET_FLAGS) -N "raco" -l- setup $(SETUP_SETUP_FLAGS) install: $(MAKE) install-@MAIN_VARIANT@ diff --git a/racket/src/configure b/racket/src/configure index 152d29f6d1..af9550f030 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -629,6 +629,7 @@ RUN_RACKET_MAIN_VARIANT RUN_RACKET_MMM RUN_RACKET_CGC INSTALL_LIBS_ENABLE +INSTALL_SETUP_RACKET_FLAGS INSTALL_SETUP_FLAGS MAIN_VARIANT CGC_CAP_INSTALLED @@ -3164,6 +3165,7 @@ CGC_CAP_INSTALLED=CGC MAIN_VARIANT=3m INSTALL_SETUP_FLAGS= +INSTALL_SETUP_RACKET_FLAGS= INSTALL_LIBS_ENABLE=no-install @@ -6622,6 +6624,7 @@ fi if test "${enable_usersetup}" != "yes" ; then INSTALL_SETUP_FLAGS="${INSTALL_SETUP_FLAGS} --no-user" + INSTALL_SETUP_RACKET_FLAGS="${INSTALL_SETUP_RACKET_FLAGS} --no-user-path" fi ############## docs ################ @@ -6846,6 +6849,7 @@ LIBS="$LIBS $EXTRALIBS" + mk_needed_dir() diff --git a/racket/src/racket/cmdline.inc b/racket/src/racket/cmdline.inc index ddee9ad5c3..e7163fc619 100644 --- a/racket/src/racket/cmdline.inc +++ b/racket/src/racket/cmdline.inc @@ -1132,6 +1132,8 @@ static int run_from_cmd_line(int argc, char *_argv[], argv[0] = "-c"; else if (!strcmp("--no-lib", argv[0])) argv[0] = "-n"; + else if (!strcmp("--no-user-path", argv[0])) + argv[0] = "-U"; else if (!strcmp("--version", argv[0])) argv[0] = "-v"; else if (!strcmp("--no-init-file", argv[0])) diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 9d0e0d5a39..1675db1ff7 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -440,6 +440,7 @@ CGC_CAP_INSTALLED=CGC MAIN_VARIANT=3m INSTALL_SETUP_FLAGS= +INSTALL_SETUP_RACKET_FLAGS= INSTALL_LIBS_ENABLE=no-install @@ -1543,6 +1544,7 @@ fi if test "${enable_usersetup}" != "yes" ; then INSTALL_SETUP_FLAGS="${INSTALL_SETUP_FLAGS} --no-user" + INSTALL_SETUP_RACKET_FLAGS="${INSTALL_SETUP_RACKET_FLAGS} --no-user-path" fi ############## docs ################ @@ -1759,6 +1761,7 @@ AC_SUBST(CGC_CAP_INSTALLED) AC_SUBST(MAIN_VARIANT) AC_SUBST(INSTALL_SETUP_FLAGS) +AC_SUBST(INSTALL_SETUP_RACKET_FLAGS) AC_SUBST(INSTALL_LIBS_ENABLE) From e0506038ba2a0ab1fda664aa6232964499a3c5b9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Sep 2015 06:13:57 -0600 Subject: [PATCH 184/381] doc database: retry on SQLITE_READONLY_ROLLBACK The SQLITE_READONLY_ROLLBACK error is supposed to mean that a crash occurred and a hot journal exists that needs to be replayed (but can't, because the current connection is read-only). In practice, it seems that the error can happen even if there has been no crash. In that case, retrying in the same was as other transient errors allows the process to continue. A possible reason for the spurious error: In the implementation of SQLite, comments in hasHotJournal() mention the possibility of false positives (ticket #3883) and how the false positive will be handled in the playback mechanism after obtaining an exclusive lock. The check for a read-only connection after hasHotJournal() is called, however, happens before that lock is acquired. So, it seems like the race condition could trigger a false SQLITE_READONLY_ROLLBACK error. --- racket/collects/db/private/sqlite3/connection.rkt | 6 ++++-- racket/collects/db/private/sqlite3/ffi-constants.rkt | 1 + racket/collects/setup/doc-db.rkt | 7 ++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/racket/collects/db/private/sqlite3/connection.rkt b/racket/collects/db/private/sqlite3/connection.rkt index 5f033ab396..59f01c7f6f 100644 --- a/racket/collects/db/private/sqlite3/connection.rkt +++ b/racket/collects/db/private/sqlite3/connection.rkt @@ -453,7 +453,8 @@ (define (simplify-status s) (cond [(or (= SQLITE_IOERR_BLOCKED s) - (= SQLITE_IOERR_LOCK s)) + (= SQLITE_IOERR_LOCK s) + (= SQLITE_READONLY_ROLLBACK s)) ;; Kept in extended form, because these indicate ;; cases where retry is appropriate s] @@ -468,6 +469,7 @@ [,SQLITE_LOCKED locked "table in the database is locked"] [,SQLITE_NOMEM nomem "malloc() failed"] [,SQLITE_READONLY readonly "attempt to write a readonly database"] + [,SQLITE_READONLY_ROLLBACK readonly-rollback "attempt to write a readonly database (hot journal)"] [,SQLITE_INTERRUPT interrupt "operation terminated by sqlite3_interrupt()"] [,SQLITE_IOERR ioerr "some kind of disk I/O error occurred"] [,SQLITE_IOERR_BLOCKED ioerr-blocked "some kind of disk I/O error occurred (blocked)"] @@ -495,7 +497,7 @@ SQLITE_IOERR_BLOCKED SQLITE_IOERR_LOCK)) (define include-db-file-status-list - (list SQLITE_READONLY SQLITE_PERM SQLITE_ABORT SQLITE_BUSY SQLITE_LOCKED + (list SQLITE_READONLY SQLITE_READONLY_ROLLBACK SQLITE_PERM SQLITE_ABORT SQLITE_BUSY SQLITE_LOCKED SQLITE_IOERR SQLITE_IOERR_BLOCKED SQLITE_IOERR_LOCK SQLITE_CORRUPT SQLITE_NOTFOUND SQLITE_FULL SQLITE_CANTOPEN SQLITE_PROTOCOL SQLITE_EMPTY SQLITE_FORMAT SQLITE_NOTADB)) diff --git a/racket/collects/db/private/sqlite3/ffi-constants.rkt b/racket/collects/db/private/sqlite3/ffi-constants.rkt index a3559d4fb0..59f0465476 100644 --- a/racket/collects/db/private/sqlite3/ffi-constants.rkt +++ b/racket/collects/db/private/sqlite3/ffi-constants.rkt @@ -35,6 +35,7 @@ ;; Extended error codes: (define SQLITE_IOERR_BLOCKED (bitwise-ior SQLITE_IOERR (arithmetic-shift 11 8))) (define SQLITE_IOERR_LOCK (bitwise-ior SQLITE_IOERR (arithmetic-shift 15 8))) +(define SQLITE_READONLY_ROLLBACK (bitwise-ior SQLITE_READONLY (arithmetic-shift 3 8))) (define SQLITE_INTEGER 1) (define SQLITE_FLOAT 2) diff --git a/racket/collects/setup/doc-db.rkt b/racket/collects/setup/doc-db.rkt index 127ba9cbf5..f5c7aafd17 100644 --- a/racket/collects/setup/doc-db.rkt +++ b/racket/collects/setup/doc-db.rkt @@ -487,7 +487,12 @@ (let ([s (exn:fail:sql-sqlstate v)]) (or (eq? s 'busy) (eq? s 'ioerr-blocked) - (eq? s 'ioerr-lock))))) + (eq? s 'ioerr-lock) + ;; The `SQLITE_READONLY_ROLLBACK` result is supposed + ;; to mean that a hot journal exists due to a crash, + ;; but it seems to happen even without crashes, so + ;; treat it is a reason to retry: + (eq? s 'readonly-rollback))))) (define (call-with-lock-handler handler thunk) (with-handlers* ([exn:fail:retry? From c160302be79d212a7037691a884eced8689893ad Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 9 Sep 2015 11:37:35 -0400 Subject: [PATCH 185/381] Bump version number for rename transformer change Refers to commit 33bb5e906086e4e0c0951d840916f8fa4bef602c --- pkgs/base/info.rkt | 2 +- racket/src/racket/src/schvers.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 3aa51238e1..79d570eae9 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.15") +(define version "6.2.900.16") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 7cd63bcc70..f7913d2faa 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.15" +#define MZSCHEME_VERSION "6.2.900.16" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 15 +#define MZSCHEME_VERSION_W 16 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From c492f763c71e42f2dffb71e62babdaadab51b3cf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Sep 2015 12:23:37 -0600 Subject: [PATCH 186/381] Visual Studio projects: put in more places Putting in the new places makes the projects work when more than one version of Visual Studio is installed. Maybe the old place was always the wrong place, or maybe VS 2010 wanted it in the old place. Either way, sprinkling the version in more places seems unlikely to hurt. --- racket/src/worksp/gracket/gracket.vcxproj | 1 + racket/src/worksp/libffi/libffi.vcxproj | 4 ++++ racket/src/worksp/libmzgc/libmzgc.vcxproj | 4 ++++ racket/src/worksp/libracket/libracket.vcxproj | 1 + racket/src/worksp/mrstart/mrstart.vcxproj | 2 ++ racket/src/worksp/mzcom/mzcom.vcxproj | 1 + racket/src/worksp/mzstart/mzstart.vcxproj | 2 ++ racket/src/worksp/sgc/sgc.vcxproj | 4 ++++ 8 files changed, 19 insertions(+) diff --git a/racket/src/worksp/gracket/gracket.vcxproj b/racket/src/worksp/gracket/gracket.vcxproj index 1a0d559168..7a52867d76 100644 --- a/racket/src/worksp/gracket/gracket.vcxproj +++ b/racket/src/worksp/gracket/gracket.vcxproj @@ -42,6 +42,7 @@ Application false MultiByte + v100 diff --git a/racket/src/worksp/libffi/libffi.vcxproj b/racket/src/worksp/libffi/libffi.vcxproj index 710e55e770..7c904451e0 100644 --- a/racket/src/worksp/libffi/libffi.vcxproj +++ b/racket/src/worksp/libffi/libffi.vcxproj @@ -27,20 +27,24 @@ StaticLibrary Unicode + v100 true StaticLibrary Unicode + v100 StaticLibrary Unicode + v100 true StaticLibrary Unicode + v100 diff --git a/racket/src/worksp/libmzgc/libmzgc.vcxproj b/racket/src/worksp/libmzgc/libmzgc.vcxproj index a76ef5d07b..3bbad1c46b 100644 --- a/racket/src/worksp/libmzgc/libmzgc.vcxproj +++ b/racket/src/worksp/libmzgc/libmzgc.vcxproj @@ -26,21 +26,25 @@ DynamicLibrary false MultiByte + v100 DynamicLibrary false MultiByte + v100 DynamicLibrary false MultiByte + v100 DynamicLibrary false MultiByte + v100 diff --git a/racket/src/worksp/libracket/libracket.vcxproj b/racket/src/worksp/libracket/libracket.vcxproj index 73a59ca01c..f63c8903e9 100644 --- a/racket/src/worksp/libracket/libracket.vcxproj +++ b/racket/src/worksp/libracket/libracket.vcxproj @@ -42,6 +42,7 @@ DynamicLibrary false MultiByte + v100 diff --git a/racket/src/worksp/mrstart/mrstart.vcxproj b/racket/src/worksp/mrstart/mrstart.vcxproj index f4ac329841..3daf265623 100644 --- a/racket/src/worksp/mrstart/mrstart.vcxproj +++ b/racket/src/worksp/mrstart/mrstart.vcxproj @@ -17,10 +17,12 @@ Application false + v100 Application false + v100 diff --git a/racket/src/worksp/mzcom/mzcom.vcxproj b/racket/src/worksp/mzcom/mzcom.vcxproj index 985e6c3498..e611b4972d 100644 --- a/racket/src/worksp/mzcom/mzcom.vcxproj +++ b/racket/src/worksp/mzcom/mzcom.vcxproj @@ -50,6 +50,7 @@ Application false MultiByte + v100 diff --git a/racket/src/worksp/mzstart/mzstart.vcxproj b/racket/src/worksp/mzstart/mzstart.vcxproj index f15bf95ec8..57e009aec9 100644 --- a/racket/src/worksp/mzstart/mzstart.vcxproj +++ b/racket/src/worksp/mzstart/mzstart.vcxproj @@ -17,10 +17,12 @@ Application false + v100 Application false + v100 diff --git a/racket/src/worksp/sgc/sgc.vcxproj b/racket/src/worksp/sgc/sgc.vcxproj index 2ff6e036d0..4ffc303a11 100644 --- a/racket/src/worksp/sgc/sgc.vcxproj +++ b/racket/src/worksp/sgc/sgc.vcxproj @@ -28,19 +28,23 @@ DynamicLibrary Unicode true + v100 DynamicLibrary Unicode + v100 DynamicLibrary Unicode true + v100 DynamicLibrary Unicode + v100 From e318257a7fa751525df68e04173274956bb9cd2f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Sep 2015 12:52:26 -0600 Subject: [PATCH 187/381] support Visual Studio 2015 Closes #996 --- INSTALL.txt | 2 +- racket/collects/compiler/private/xform.rkt | 1 + racket/src/worksp/genvsx.c | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/INSTALL.txt b/INSTALL.txt index 5b96efcad5..35be1bbb4e 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -57,7 +57,7 @@ On Unix (including Linux) and Mac OS X, `make' (or `make in-place') creates a build in the "racket" directory. On Windows with Microsoft Visual Studio (any version between 2008/9.0 -and 2013/12.0), `nmake win32-in-place' creates a build in the "racket" +and 2015/14.0), `nmake win32-in-place' creates a build in the "racket" directory. For information on configuring your command-line environment for Visual Studio, see "racket/src/worksp/README". diff --git a/racket/collects/compiler/private/xform.rkt b/racket/collects/compiler/private/xform.rkt index 534fabb736..42b6988036 100644 --- a/racket/collects/compiler/private/xform.rkt +++ b/racket/collects/compiler/private/xform.rkt @@ -907,6 +907,7 @@ __error __errno_location __toupper __tolower ___errno __attribute__ __mode__ ; not really functions in gcc __iob_func ; VC 8 + __acrt_iob_func ; VC 14.0 (2015) |GetStdHandle| |__CFStringMakeConstantString| _vswprintf_c diff --git a/racket/src/worksp/genvsx.c b/racket/src/worksp/genvsx.c index f30dd79505..02b4d0acab 100644 --- a/racket/src/worksp/genvsx.c +++ b/racket/src/worksp/genvsx.c @@ -86,7 +86,10 @@ int main() { const char *vers = "100"; int i; -#if _MSC_VER >= 1800 +#if _MSC_VER >= 1900 + /* VS 2015 */ + vers = "140"; +#elif _MSC_VER >= 1800 /* VS 2013 */ vers = "120"; #elif _MSC_VER >= 1700 From 9bf68db7f72755bf90a820305aa69abfe059e3ee Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Sep 2015 12:45:54 -0600 Subject: [PATCH 188/381] raco pkg: use Git protocol for GitHub sources Using the GitHub API for GitHub sources can run afoul of API limits. Since we now support the Git protocol generall, use that for GitHub sources, too. Set the `PLT_USE_GITHUB_API` environment variable to use the GitHub API, instead. --- pkgs/racket-doc/pkg/scribblings/pkg.scrbl | 14 ++++++++++--- racket/collects/pkg/private/clone-path.rkt | 6 +++--- racket/collects/pkg/private/download.rkt | 11 ++++++++--- racket/collects/pkg/private/orig-pkg.rkt | 2 +- racket/collects/pkg/private/repo-path.rkt | 22 +++++++++++++-------- racket/collects/pkg/private/stage.rkt | 23 ++++++++++++++-------- 6 files changed, 52 insertions(+), 26 deletions(-) diff --git a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl index 354bf9fc97..c580f061d3 100644 --- a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -285,8 +285,8 @@ is a GitHub package source. @margin-note{A Github repository source that starts with @litchar{git://} obtains the same content that would be accessed if @litchar{github.com} were not treated specially. The special treatment -is preserved for historical reasons and because GitHub provides an -interface that is always efficient.} +is preserved for historical reasons, especially in combination +with @envvar{PLT_USE_GITHUB_API}.} For backward compatibility, an older format is also supported: @@ -304,7 +304,15 @@ with @litchar{git://github.com/} or @litchar{github://}; a package source that is otherwise specified as a GitHub reference is automatically prefixed with @litchar{git://github.com/}. The inferred package name is the last element of @nonterm{path} if it is non-empty, -otherwise the inferred name is @nonterm{repo}.} +otherwise the inferred name is @nonterm{repo}. + +If the @indexed-envvar{PLT_USE_GITHUB_API} environment variable is +set, GitHub packages are obtained using the GitHub API protocol +instead of using the Git protocol. + +@history[#:changed "6.2.900.16" @elem{Changed handling of + GitHub sources to use the Git + protocol by default.}]} @; ---------------------------------------- @item{a @tech{package name} --- A @tech{package catalog} is diff --git a/racket/collects/pkg/private/clone-path.rkt b/racket/collects/pkg/private/clone-path.rkt index f7d79f7ee1..c6635fa9a6 100644 --- a/racket/collects/pkg/private/clone-path.rkt +++ b/racket/collects/pkg/private/clone-path.rkt @@ -372,9 +372,9 @@ [else #f])] [(git github clone) (define pkg-url (string->url (pkg-desc-source d))) - (define-values (host port repo branch path) - (split-git-or-hub-url pkg-url)) - (real-git-url pkg-url host port repo)] + (define-values (transport host port repo branch path) + (split-git-or-hub-url #:type type pkg-url)) + (real-git-url pkg-url #:type type host port repo)] [else #f]))) (define (pkg-info->clone-desc name info diff --git a/racket/collects/pkg/private/download.rkt b/racket/collects/pkg/private/download.rkt index 0fd31d07c1..93325312c2 100644 --- a/racket/collects/pkg/private/download.rkt +++ b/racket/collects/pkg/private/download.rkt @@ -98,7 +98,7 @@ #:log-debug-string (lambda (s) (log-pkg-debug s)))))) -(define (download-repo! url host port repo dest-dir checksum +(define (download-repo! url transport host port repo dest-dir checksum #:download-printf [download-printf #f] #:use-cache? [use-cache? #t]) (log-pkg-debug "\t\tDownloading ~a to ~a" (url->string url) dest-dir) @@ -107,11 +107,16 @@ (define unpacked? #f) (define (download!) + (when download-printf + (download-printf "Downloading repository ~a\n" (url->string url))) (git-checkout host #:port port repo #:dest-dir dest-dir #:ref checksum - #:status-printf (or download-printf void) - #:transport (string->symbol (url-scheme url))) + #:status-printf (lambda (fmt . args) + (define (strip-ending-newline s) + (regexp-replace #rx"\n$" s "")) + (log-pkg-debug (strip-ending-newline (apply format fmt args)))) + #:transport transport) (set! unpacked? #t) ;; package directory as ".tgz" so it can be cached: (parameterize ([current-directory dest-dir]) diff --git a/racket/collects/pkg/private/orig-pkg.rkt b/racket/collects/pkg/private/orig-pkg.rkt index 1c62ecc29c..4bd4d93906 100644 --- a/racket/collects/pkg/private/orig-pkg.rkt +++ b/racket/collects/pkg/private/orig-pkg.rkt @@ -22,7 +22,7 @@ (simple-form-path src) #:more-than-root? #t)))] [(clone) - (define-values (host port repo branch path) + (define-values (transport host port repo branch path) (split-git-or-hub-url (string->url src))) `(clone ,(path->string (find-relative-path (pkg-installed-dir) diff --git a/racket/collects/pkg/private/repo-path.rkt b/racket/collects/pkg/private/repo-path.rkt index acc9d91e46..a6589192c1 100644 --- a/racket/collects/pkg/private/repo-path.rkt +++ b/racket/collects/pkg/private/repo-path.rkt @@ -12,7 +12,10 @@ split-git-url split-git-or-hub-url enclosing-path-for-repo - real-git-url) + real-git-url + use-git-for-github?) + +(define use-git-for-github? (not (getenv "PLT_USE_GITHUB_API"))) (define (split-github-url pkg-url) (if (equal? (url-scheme pkg-url) "github") @@ -32,7 +35,8 @@ ;; returns: (values host repo branch path) (define (split-git-url pkg-url) - (values (url-host pkg-url) + (values (string->symbol (url-scheme pkg-url)) + (url-host pkg-url) (url-port pkg-url) (string-join (map (compose ~a path/param-path) (url-path/no-slash pkg-url)) @@ -40,15 +44,16 @@ (or (url-fragment pkg-url) "master") (extract-git-path pkg-url))) -(define (split-git-or-hub-url pkg-url) - (if (equal? "github" (url-scheme pkg-url)) +(define (split-git-or-hub-url pkg-url #:type [type #f]) + (if (or (equal? "github" (url-scheme pkg-url)) + (eq? type 'github)) (match (split-github-url pkg-url) [(list* user repo branch path) - (values "github.com" #f (~a "/" user "/" repo) branch path)]) + (values 'git "github.com" #f (~a user "/" repo) branch path)]) (split-git-url pkg-url))) (define (enclosing-path-for-repo url-str in-repo-dir) - (define-values (host port repo branch path) + (define-values (transport host port repo branch path) (split-git-or-hub-url (string->url url-str))) (let loop ([path path] [in-repo-dir (simplify-path in-repo-dir)]) @@ -60,9 +65,10 @@ (error "path for git repo link is too short for path in package source") (loop (cdr path) base))]))) -(define (real-git-url pkg-url host port repo) +(define (real-git-url pkg-url host port repo #:type [type #f]) (url->string - (if (equal? "github" (url-scheme pkg-url)) + (if (or (equal? "github" (url-scheme pkg-url)) + (eq? type 'github)) ;; Convert "github://" to a real URL: (url "https" #f host port #t (map (lambda (s) (path/param s null)) (string-split repo "/")) diff --git a/racket/collects/pkg/private/stage.rkt b/racket/collects/pkg/private/stage.rkt index ca3ab5f24e..f62a5a578a 100644 --- a/racket/collects/pkg/private/stage.rkt +++ b/racket/collects/pkg/private/stage.rkt @@ -40,6 +40,12 @@ (struct install-info (name orig-pkg directory git-directory clean? checksum module-paths additional-installs)) +(define (communication-type type) + (if (and (eq? type 'github) + use-git-for-github?) + 'git + type)) + (define (remote-package-checksum pkg download-printf pkg-name #:type [type #f] #:catalog-lookup-cache [catalog-lookup-cache #f] @@ -123,7 +129,7 @@ #:force-strip? force-strip?)] [(eq? type 'clone) (define pkg-url (string->url pkg)) - (define-values (host port repo branch path) + (define-values (transport host port repo branch path) (split-git-or-hub-url pkg-url)) (define pkg-no-query (real-git-url pkg-url host port repo)) (define clone-dir (or given-at-dir @@ -245,14 +251,15 @@ (check-checksum given-checksum found-checksum "unexpected" pkg #f)) (define checksum (or found-checksum given-checksum)) (define downloaded-info - (match type + (match (communication-type type) ['git (when (equal? checksum "") (pkg-error (~a "cannot use empty checksum for Git repostory package source\n" " source: ~a") pkg)) - (define-values (host port repo branch path) (split-git-url pkg-url)) + (define-values (transport host port repo branch path) + (split-git-or-hub-url pkg-url #:type type)) (define tmp-dir (make-temporary-file (string-append @@ -264,7 +271,7 @@ (dynamic-wind void (λ () - (download-repo! pkg-url host port repo tmp-dir checksum + (download-repo! pkg-url transport host port repo tmp-dir checksum #:use-cache? use-cache? #:download-printf download-printf) (lift-git-directory-content tmp-dir path) @@ -696,10 +703,10 @@ (or given-type (let-values ([(name type) (package-source->name+type pkg-url-str given-type)]) type)))) - (case type + (case (communication-type type) [(git) - (define-values (host port repo branch path) - (split-git-url pkg-url)) + (define-values (transport host port repo branch path) + (split-git-or-hub-url pkg-url #:type type)) (download-printf "Querying Git references for ~a at ~a\n" pkg-name pkg-url-str) ;; Supplying `#:dest-dir #f` means that we just resolve `branch` ;; to an ID: @@ -715,7 +722,7 @@ " the given URL might not refer to a Git repository\n" " given URL: ~a") pkg-url-str)) - #:transport (string->symbol (url-scheme pkg-url)))] + #:transport transport)] [(github) (match-define (list* user repo branch path) (split-github-url pkg-url)) From 5aebb1c53931b10480a0d400a7354f14a03b2fa8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Sep 2015 20:53:27 -0600 Subject: [PATCH 189/381] raco pkg: get catalog info and checksums in parallel When `raco pkg {install,update}` has a list of packages to check, first run through the list in a "prefetch" mode to create futures to fetch the information. Issuing requests to servers in parallel can greatly speed up `raco pkg update --all`. Package content is still downloaded sequentially. --- racket/collects/pkg/private/install.rkt | 592 +++++++++++++---------- racket/collects/pkg/private/prefetch.rkt | 187 +++++++ racket/collects/pkg/private/stage.rkt | 46 +- 3 files changed, 555 insertions(+), 270 deletions(-) create mode 100644 racket/collects/pkg/private/prefetch.rkt diff --git a/racket/collects/pkg/private/install.rkt b/racket/collects/pkg/private/install.rkt index 9eb7aaf1f8..4b6ff339a0 100644 --- a/racket/collects/pkg/private/install.rkt +++ b/racket/collects/pkg/private/install.rkt @@ -31,19 +31,29 @@ "orig-pkg.rkt" "info-to-desc.rkt" "git.rkt" - "check-will-exist.rkt") + "check-will-exist.rkt" + "prefetch.rkt") (provide pkg-install pkg-update) +;; A [prefetch-shared] annotation means that a hash table is shared +;; with prefetch threads. If a prefetch group is terminated, then all +;; prefetch-shared tables must be abaondoned, because a thread with a +;; lock can be terminated. + (define (checksum-for-pkg-source pkg-source type pkg-name given-checksum download-printf - #:catalog-lookup-cache [catalog-lookup-cache #f] - #:remote-checksum-cache [remote-checksum-cache #f]) + #:prefetch? [prefetch? #f] + #:prefetch-group [prefetch-group #f] + #:catalog-lookup-cache [catalog-lookup-cache #f] ; [prefetch-shared] + #:remote-checksum-cache [remote-checksum-cache #f]) ; [prefetch-shared] (case type [(file-url dir-url github git clone) (or given-checksum (remote-package-checksum `(url ,pkg-source) download-printf pkg-name #:type type + #:prefetch? prefetch? + #:prefetch-group prefetch-group #:catalog-lookup-cache catalog-lookup-cache #:remote-checksum-cache remote-checksum-cache))] [(file) @@ -56,6 +66,8 @@ (or given-checksum (remote-package-checksum `(catalog ,pkg-source) download-printf pkg-name #:type type + #:prefetch? prefetch? + #:prefetch-group prefetch-group #:catalog-lookup-cache catalog-lookup-cache #:remote-checksum-cache remote-checksum-cache))] [else given-checksum])) @@ -134,8 +146,9 @@ #:update-deps? update-deps? #:update-implies? update-implies? #:update-cache update-cache - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache + #:prefetch-group prefetch-group + #:catalog-lookup-cache catalog-lookup-cache ; [prefetch-shared] + #:remote-checksum-cache remote-checksum-cache ; [prefetch-shared] #:updating? updating-all? #:extra-updating extra-updating #:ignore-checksums? ignore-checksums? @@ -416,20 +429,23 @@ (or do-update-deps? (set-member? implies name)) (not (hash-ref simultaneous-installs name #f)) - ((packages-to-update download-printf current-scope-db - #:must-update? #f - #:deps? do-update-deps? - #:implies? update-implies? - #:update-cache update-cache - #:namespace metadata-ns - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache - #:all-platforms? all-platforms? - #:ignore-checksums? ignore-checksums? - #:use-cache? use-cache? - #:from-command-line? from-command-line? - #:link-dirs? link-dirs?) - name)) + (let ([updater + (packages-to-update download-printf current-scope-db + #:must-update? #f + #:deps? do-update-deps? + #:implies? update-implies? + #:update-cache update-cache + #:prefetch-group prefetch-group + #:namespace metadata-ns + #:catalog-lookup-cache catalog-lookup-cache + #:remote-checksum-cache remote-checksum-cache + #:all-platforms? all-platforms? + #:ignore-checksums? ignore-checksums? + #:use-cache? use-cache? + #:from-command-line? from-command-line? + #:link-dirs? link-dirs?)]) + (updater #:prefetch? #t name) + (updater name))) null)) deps)) (and (not (empty? update-pkgs)) @@ -527,19 +543,21 @@ (define update-pkgs (map car update-deps)) (define (make-pre-succeed) (define db current-scope-db) - (let ([to-update (append-map (packages-to-update download-printf db - #:deps? update-deps? - #:implies? update-implies? - #:update-cache update-cache - #:namespace metadata-ns - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache - #:all-platforms? all-platforms? - #:ignore-checksums? ignore-checksums? - #:use-cache? use-cache? - #:from-command-line? from-command-line? - #:link-dirs? link-dirs?) - update-pkgs)]) + (let ([to-update (let ([updater (packages-to-update download-printf db + #:deps? update-deps? + #:implies? update-implies? + #:update-cache update-cache + #:prefetch-group prefetch-group + #:namespace metadata-ns + #:catalog-lookup-cache catalog-lookup-cache + #:remote-checksum-cache remote-checksum-cache + #:all-platforms? all-platforms? + #:ignore-checksums? ignore-checksums? + #:use-cache? use-cache? + #:from-command-line? from-command-line? + #:link-dirs? link-dirs?)]) + (for ([pkg (in-list update-pkgs)]) (updater #:prefetch? #t pkg)) + (append-map updater update-pkgs))]) (λ () (for-each (compose (remove-package #t quiet? use-trash?) pkg-desc-name) to-update)))) (match this-dep-behavior ['fail @@ -820,8 +838,9 @@ #:update-deps? [update-deps? #f] #:update-implies? [update-implies? #t] #:update-cache [update-cache (make-hash)] - #:catalog-lookup-cache [catalog-lookup-cache (make-hash)] - #:remote-checksum-cache [remote-checksum-cache (make-hash)] + #:prefetch-group [prefetch-group (make-prefetch-group)] + #:catalog-lookup-cache [catalog-lookup-cache (make-hash)] ; [prefetch-shared] + #:remote-checksum-cache [remote-checksum-cache (make-hash)] ; [prefetch-shared] #:check-pkg-early? [check-pkg-early? #t] #:updating? [updating? #f] #:quiet? [quiet? #f] @@ -874,89 +893,95 @@ download-printf from-command-line? convert-to-non-clone?)) - (with-handlers* ([vector? - (match-lambda - [(vector updating? new-infos dep-pkg deps more-pre-succeed conv clone-info) - (pkg-install - #:summary-deps (snoc summary-deps (vector dep-pkg deps)) - #:old-infos new-infos - #:old-descs (append done-descs new-descs) - #:all-platforms? all-platforms? - #:force? force - #:ignore-checksums? ignore-checksums? - #:strict-doc-conflicts? strict-doc-conflicts? - #:use-cache? use-cache? - #:dep-behavior dep-behavior - #:update-deps? update-deps? - #:update-implies? update-implies? - #:update-cache update-cache - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache - #:check-pkg-early? #f - #:pre-succeed (lambda () (pre-succeed) (more-pre-succeed)) - #:updating? updating? - #:quiet? quiet? - #:use-trash? use-trash? - #:from-command-line? from-command-line? - #:conversation conv - #:strip strip-mode - #:force-strip? force-strip? - #:multi-clone-behavior (vector-ref clone-info 0) - #:repo-descs (vector-ref clone-info 1) - #:pull-behavior pull-behavior - (for/list ([dep (in-list deps)]) - (if (pkg-desc? dep) - dep - (pkg-desc dep #f #f #f #t #f))))])]) - (begin0 - (install-packages - #:old-infos done-infos - #:old-descs done-descs - #:all-platforms? all-platforms? - #:force? force - #:ignore-checksums? ignore-checksums? - #:use-cache? use-cache? - #:skip-installed? skip-installed? - #:dep-behavior dep-behavior - #:update-deps? update-deps? - #:update-implies? update-implies? - #:update-cache update-cache - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache - #:pre-succeed (λ () - (for ([pkg-name (in-hash-keys extra-updating)]) - ((remove-package #t quiet? use-trash?) pkg-name)) - (pre-succeed)) - #:updating? updating? - #:extra-updating extra-updating - #:quiet? quiet? - #:use-trash? use-trash? - #:from-command-line? from-command-line? - #:conversation conversation - #:strip strip-mode - #:force-strip? force-strip? - #:link-dirs? link-dirs? - #:local-docs-ok? (not strict-doc-conflicts?) - #:ai-cache (box #f) - #:clone-info (vector clone-behavior - repo-descs) - #:pull-behavior pull-behavior - new-descs) - (unless (empty? summary-deps) - (unless quiet? - (printf/flush "The following~a packages were listed as dependencies~a:~a\n" - (if updating? " out-of-date" " uninstalled") - (format "\nand they were ~a~a" - (if (eq? dep-behavior 'search-auto) "automatically " "") - (if updating? "updated" "installed")) - (string-append* - (for/list ([p*ds (in-list summary-deps)]) - (match-define (vector n ds) p*ds) - (format "\n dependencies of ~a:~a" - n - (if updating? - (format-deps ds) - (format-list ds))))))))))) + + (call-with-prefetch-cleanup + prefetch-group + (lambda () + (with-handlers* ([vector? + (match-lambda + [(vector updating? new-infos dep-pkg deps more-pre-succeed conv clone-info) + (pkg-install + #:summary-deps (snoc summary-deps (vector dep-pkg deps)) + #:old-infos new-infos + #:old-descs (append done-descs new-descs) + #:all-platforms? all-platforms? + #:force? force + #:ignore-checksums? ignore-checksums? + #:strict-doc-conflicts? strict-doc-conflicts? + #:use-cache? use-cache? + #:dep-behavior dep-behavior + #:update-deps? update-deps? + #:update-implies? update-implies? + #:update-cache update-cache + #:prefetch-group prefetch-group + #:catalog-lookup-cache catalog-lookup-cache + #:remote-checksum-cache remote-checksum-cache + #:check-pkg-early? #f + #:pre-succeed (lambda () (pre-succeed) (more-pre-succeed)) + #:updating? updating? + #:quiet? quiet? + #:use-trash? use-trash? + #:from-command-line? from-command-line? + #:conversation conv + #:strip strip-mode + #:force-strip? force-strip? + #:multi-clone-behavior (vector-ref clone-info 0) + #:repo-descs (vector-ref clone-info 1) + #:pull-behavior pull-behavior + (for/list ([dep (in-list deps)]) + (if (pkg-desc? dep) + dep + (pkg-desc dep #f #f #f #t #f))))])]) + (begin0 + (install-packages + #:old-infos done-infos + #:old-descs done-descs + #:all-platforms? all-platforms? + #:force? force + #:ignore-checksums? ignore-checksums? + #:use-cache? use-cache? + #:skip-installed? skip-installed? + #:dep-behavior dep-behavior + #:update-deps? update-deps? + #:update-implies? update-implies? + #:update-cache update-cache + #:prefetch-group prefetch-group + #:catalog-lookup-cache catalog-lookup-cache + #:remote-checksum-cache remote-checksum-cache + #:pre-succeed (λ () + (for ([pkg-name (in-hash-keys extra-updating)]) + ((remove-package #t quiet? use-trash?) pkg-name)) + (pre-succeed)) + #:updating? updating? + #:extra-updating extra-updating + #:quiet? quiet? + #:use-trash? use-trash? + #:from-command-line? from-command-line? + #:conversation conversation + #:strip strip-mode + #:force-strip? force-strip? + #:link-dirs? link-dirs? + #:local-docs-ok? (not strict-doc-conflicts?) + #:ai-cache (box #f) + #:clone-info (vector clone-behavior + repo-descs) + #:pull-behavior pull-behavior + new-descs) + (unless (empty? summary-deps) + (unless quiet? + (printf/flush "The following~a packages were listed as dependencies~a:~a\n" + (if updating? " out-of-date" " uninstalled") + (format "\nand they were ~a~a" + (if (eq? dep-behavior 'search-auto) "automatically " "") + (if updating? "updated" "installed")) + (string-append* + (for/list ([p*ds (in-list summary-deps)]) + (match-define (vector n ds) p*ds) + (format "\n dependencies of ~a:~a" + n + (if updating? + (format-deps ds) + (format-list ds))))))))))))) ;; Determine packages to update, starting with `pkg-name'. If `pkg-name' ;; needs to be updated, return it in a list. Otherwise, if `deps?', @@ -974,9 +999,10 @@ #:deps? deps? #:implies? implies? #:namespace metadata-ns - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache + #:catalog-lookup-cache catalog-lookup-cache ; [prefetch-shared] + #:remote-checksum-cache remote-checksum-cache ; [prefetch-shared] #:update-cache update-cache + #:prefetch-group prefetch-group #:all-platforms? all-platforms? #:ignore-checksums? ignore-checksums? #:use-cache? use-cache? @@ -985,11 +1011,17 @@ #:skip-uninstalled? [skip-uninstalled? #f] #:all-mode? [all-mode? #f] #:force-update? [force-update? #f]) - pkg-name) + pkg-name + ;; In prefetch mode, do as much work as possible to generate + ;; server requests without waiting for results and without + ;; making any other state changes --- but forced errors are + ;; ok. + #:prefetch? [prefetch? #f]) (let update-loop ([pkg-name pkg-name] [must-update? must-update?] [force-update? force-update?] - [report-skip? #t]) + [report-skip? #t] + [prefetch? prefetch?]) (cond [(pkg-desc? pkg-name) ;; Infer the package-source type and name: @@ -1013,46 +1045,59 @@ name (pkg-desc-checksum pkg-name) download-printf + #:prefetch? prefetch? + #:prefetch-group prefetch-group #:catalog-lookup-cache catalog-lookup-cache #:remote-checksum-cache remote-checksum-cache)) - (hash-set! update-cache name new-checksum) ; record downloaded checksum - (unless (or ignore-checksums? (not (pkg-desc-checksum pkg-name))) - (unless (equal? (pkg-desc-checksum pkg-name) new-checksum) - (pkg-error (~a "incorrect checksum on package\n" - " package source: ~a\n" - " expected: ~e\n" - " got: ~e") - (pkg-desc-source pkg-name) - (pkg-desc-checksum pkg-name) - new-checksum))) - - (if (or force-update? - (not (equal? (pkg-info-checksum info) - new-checksum)) - ;; No checksum available => always update - (not new-checksum) - ;; Different source => always update - (not (same-orig-pkg? (pkg-info-orig-pkg info) - (desc->orig-pkg type - (pkg-desc-source pkg-name) - (pkg-desc-extra-path pkg-name))))) - ;; Update: - (begin - (hash-set! update-cache (box name) #t) - (list (pkg-desc (pkg-desc-source pkg-name) - (pkg-desc-type pkg-name) - name - (pkg-desc-checksum pkg-name) - (pkg-desc-auto? pkg-name) - (or (pkg-desc-extra-path pkg-name) - (and (eq? type 'clone) - (current-directory)))))) - ;; No update needed, but maybe check dependencies: - (if (or deps? - implies?) - (update-loop name #f #f #f) - null))])] - [(hash-ref update-cache (box pkg-name) #f) + (cond + [prefetch? + ;; Don't proceed further if we're just issuing prefetches + null] + [else + (hash-set! update-cache name new-checksum) ; record downloaded checksum + (unless (or ignore-checksums? (not (pkg-desc-checksum pkg-name))) + (unless (equal? (pkg-desc-checksum pkg-name) new-checksum) + (pkg-error (~a "incorrect checksum on package\n" + " package source: ~a\n" + " expected: ~e\n" + " got: ~e") + (pkg-desc-source pkg-name) + (pkg-desc-checksum pkg-name) + new-checksum))) + + (if (or force-update? + ;; Different checksum => update + (not (equal? (pkg-info-checksum info) + new-checksum)) + ;; No checksum available => always update + (not new-checksum) + ;; Different source => always update + (not (same-orig-pkg? (pkg-info-orig-pkg info) + (desc->orig-pkg type + (pkg-desc-source pkg-name) + (pkg-desc-extra-path pkg-name))))) + ;; Update: + (begin + (hash-set! update-cache (box name) #t) + (list (pkg-desc (pkg-desc-source pkg-name) + (pkg-desc-type pkg-name) + name + (pkg-desc-checksum pkg-name) + (pkg-desc-auto? pkg-name) + (or (pkg-desc-extra-path pkg-name) + (and (eq? type 'clone) + (current-directory)))))) + ;; No update needed, but maybe check dependencies: + (if (or deps? + implies?) + (update-loop name #f #f #f prefetch?) + null))])])] + [(and prefetch? + (hash-ref (prefetch-group-in-progress prefetch-group) pkg-name #f)) + ;; Already covered for prefetch + null] + [(and (not prefetch?) + (hash-ref update-cache (box pkg-name) #f)) ;; package is already being updated null] ;; A string indicates that package source that should be @@ -1083,22 +1128,26 @@ ;; needing an update, even if it is installed as a link, so ;; that the user is asked about installing dependencies, etc. (log-pkg-debug "Missing dependencies of ~s: ~s" pkg-name missing-deps) - (update-loop (pkg-info->desc pkg-name info) #f #t #t)] + (update-loop (pkg-info->desc pkg-name info) #f #t #t prefetch?)] [else (k)])) (define (update-dependencies) - (hash-set! update-cache (box pkg-name) #t) + ;; Mark in progress: + (if prefetch? + (hash-set! (prefetch-group-in-progress prefetch-group) pkg-name #t) + (hash-set! update-cache (box pkg-name) #t)) + ;; Dependencies? (if (or deps? implies?) ;; Check dependencies (append-map - (lambda (dep) (update-loop dep #f #f #t)) + (lambda (dep) (update-loop dep #f #f #t prefetch?)) deps) null)) (define (skip/update-dependencies kind) (check-missing-dependencies (lambda () - (unless (or all-mode? (not report-skip?)) + (unless (or all-mode? (not report-skip?) prefetch?) (download-printf "Skipping update of ~a: ~a\n" kind pkg-name)) @@ -1148,20 +1197,27 @@ (hash-ref update-cache pkg-name (lambda () (remote-package-checksum orig-pkg download-printf pkg-name + #:prefetch? prefetch? + #:prefetch-group prefetch-group #:catalog-lookup-cache catalog-lookup-cache #:remote-checksum-cache remote-checksum-cache)))) ;; Record downloaded checksum: - (hash-set! update-cache pkg-name new-checksum) + (unless prefetch? + (hash-set! update-cache pkg-name new-checksum)) (or (and new-checksum (not (equal? checksum new-checksum)) ;; Update it: - (begin + (cond + [prefetch? + ;; Don't proceed further if we're just issuing prefetches + null] + [else ;; Flush cache of downloaded checksums, in case ;; there was a race between our checkig and updates on ;; the catalog server: (clear-checksums-in-cache! update-cache) (list (pkg-desc orig-pkg-source orig-pkg-type pkg-name #f auto? - orig-pkg-dir)))) + orig-pkg-dir))])) ;; Continue with dependencies, maybe (check-missing-dependencies update-dependencies))]))] [else null]))) @@ -1199,103 +1255,113 @@ (early-check-for-installed in-pkgs db #:wanted? #t)) in-pkgs])) (define update-cache (make-hash)) - (define catalog-lookup-cache (make-hash)) - (define remote-checksum-cache (make-hash)) - (define to-updat* (append-map (packages-to-update download-printf db - #:must-update? (and (not all-mode?) - (not update-deps?)) - #:deps? (or update-deps? - all-mode?) ; avoid races - #:implies? update-implies? - #:update-cache update-cache - #:namespace metadata-ns - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache - #:all-platforms? all-platforms? - #:ignore-checksums? ignore-checksums? - #:use-cache? use-cache? - #:from-command-line? from-command-line? - #:skip-uninstalled? skip-uninstalled? - #:link-dirs? link-dirs? - #:all-mode? all-mode?) - (map (compose - (if infer-clone-from-dir? - (convert-directory-to-installed-clone db) - values) - (if lookup-for-clone? - (convert-clone-name-to-clone-repo/install catalog-lookup-cache - download-printf) - (convert-clone-name-to-clone-repo/update db - skip-uninstalled? - from-command-line?))) - pkgs))) - (cond - [(empty? pkgs) - (unless quiet? - (cond - [all? - (printf/flush (~a "No updates available; no packages installed in ~a scope\n") - (current-pkg-scope))] - [else - (printf/flush (~a "No packages given to update" - (if from-command-line? - (~a - ";\n use `--all' to update all packages, or run from a package's directory" - "\n to update that package") - "") - "\n"))])) - 'skip] - [(empty? to-updat*) - (unless quiet? - (printf/flush "No updates available\n")) - 'skip] - [else - (define to-update - (hash-values - (for/fold ([ht #hash()]) ([u (in-list to-updat*)]) - (cond - [(hash-ref ht (pkg-desc-name u) #f) - => (lambda (v) - (cond - [(pkg-desc=? v u) ht] - [else - (pkg-error (~a "cannot update with conflicting update information;\n" - " package name: ~a") - (pkg-desc-name u))]))] - [else - (hash-set ht (pkg-desc-name u) u)])))) - (unless quiet? - (printf "Updating:\n") - (for ([u (in-list to-update)]) - (printf " ~a\n" (pkg-desc-name u))) - (flush-output)) - (pkg-install - #:updating? #t - #:pre-succeed (λ () (for-each (compose (remove-package #t quiet? use-trash?) pkg-desc-name) to-update)) - #:dep-behavior dep-behavior - #:update-deps? update-deps? - #:update-implies? update-implies? - #:update-cache update-cache - #:catalog-lookup-cache catalog-lookup-cache - #:remote-checksum-cache remote-checksum-cache - #:check-pkg-early? #f - #:quiet? quiet? - #:use-trash? use-trash? - #:from-command-line? from-command-line? - #:strip strip-mode - #:force-strip? force-strip? - #:all-platforms? all-platforms? - #:force? force? - #:ignore-checksums? ignore-checksums? - #:strict-doc-conflicts? strict-doc-conflicts? - #:use-cache? use-cache? - #:link-dirs? link-dirs? - #:multi-clone-behavior clone-behavior - #:convert-to-non-clone? (and lookup-for-clone? - (andmap pkg-desc? in-pkgs) - (not (ormap pkg-desc-extra-path in-pkgs))) - #:pull-behavior pull-behavior - to-update)])) + (define prefetch-group (make-prefetch-group)) + (define catalog-lookup-cache (make-hash)) ; [prefetch-shared] + (define remote-checksum-cache (make-hash)) ; [prefetch-shared] + (call-with-prefetch-cleanup + prefetch-group + (lambda () + (define to-updat* (let ([updater (packages-to-update download-printf db + #:must-update? (and (not all-mode?) + (not update-deps?)) + #:deps? (or update-deps? + all-mode?) ; avoid races + #:implies? update-implies? + #:update-cache update-cache + #:prefetch-group prefetch-group + #:namespace metadata-ns + #:catalog-lookup-cache catalog-lookup-cache + #:remote-checksum-cache remote-checksum-cache + #:all-platforms? all-platforms? + #:ignore-checksums? ignore-checksums? + #:use-cache? use-cache? + #:from-command-line? from-command-line? + #:skip-uninstalled? skip-uninstalled? + #:link-dirs? link-dirs? + #:all-mode? all-mode?)] + [pkgs (map (compose + (if infer-clone-from-dir? + (convert-directory-to-installed-clone db) + values) + (if lookup-for-clone? + (convert-clone-name-to-clone-repo/install catalog-lookup-cache + download-printf) + (convert-clone-name-to-clone-repo/update db + skip-uninstalled? + from-command-line?))) + pkgs)]) + ;; Prefetch packages info and checksums: + (for ([pkg (in-list pkgs)]) (updater #:prefetch? #t pkg)) + ;; Build update info: + (append-map updater pkgs))) + (cond + [(empty? pkgs) + (unless quiet? + (cond + [all? + (printf/flush (~a "No updates available; no packages installed in ~a scope\n") + (current-pkg-scope))] + [else + (printf/flush (~a "No packages given to update" + (if from-command-line? + (~a + ";\n use `--all' to update all packages, or run from a package's directory" + "\n to update that package") + "") + "\n"))])) + 'skip] + [(empty? to-updat*) + (unless quiet? + (printf/flush "No updates available\n")) + 'skip] + [else + (define to-update + (hash-values + (for/fold ([ht #hash()]) ([u (in-list to-updat*)]) + (cond + [(hash-ref ht (pkg-desc-name u) #f) + => (lambda (v) + (cond + [(pkg-desc=? v u) ht] + [else + (pkg-error (~a "cannot update with conflicting update information;\n" + " package name: ~a") + (pkg-desc-name u))]))] + [else + (hash-set ht (pkg-desc-name u) u)])))) + (unless quiet? + (printf "Updating:\n") + (for ([u (in-list to-update)]) + (printf " ~a\n" (pkg-desc-name u))) + (flush-output)) + (pkg-install + #:updating? #t + #:pre-succeed (λ () (for-each (compose (remove-package #t quiet? use-trash?) pkg-desc-name) to-update)) + #:dep-behavior dep-behavior + #:update-deps? update-deps? + #:update-implies? update-implies? + #:update-cache update-cache + #:prefetch-group prefetch-group + #:catalog-lookup-cache catalog-lookup-cache + #:remote-checksum-cache remote-checksum-cache + #:check-pkg-early? #f + #:quiet? quiet? + #:use-trash? use-trash? + #:from-command-line? from-command-line? + #:strip strip-mode + #:force-strip? force-strip? + #:all-platforms? all-platforms? + #:force? force? + #:ignore-checksums? ignore-checksums? + #:strict-doc-conflicts? strict-doc-conflicts? + #:use-cache? use-cache? + #:link-dirs? link-dirs? + #:multi-clone-behavior clone-behavior + #:convert-to-non-clone? (and lookup-for-clone? + (andmap pkg-desc? in-pkgs) + (not (ormap pkg-desc-extra-path in-pkgs))) + #:pull-behavior pull-behavior + to-update)])))) ;; ---------------------------------------- diff --git a/racket/collects/pkg/private/prefetch.rkt b/racket/collects/pkg/private/prefetch.rkt new file mode 100644 index 0000000000..4400d20e4e --- /dev/null +++ b/racket/collects/pkg/private/prefetch.rkt @@ -0,0 +1,187 @@ +#lang racket/base +(require racket/async-channel) + +(provide make-prefetch-group + prefetch-group-in-progress + call-with-prefetch-cleanup + make-prefetch-future + prefetch-future? + prefetch-touch) + +;; A prefetch is a kind of future for getting package info from +;; a catalog or getting a checksum from a remote source. We +;; run at most `MAX-PARALLEL` of them at once, and we avoid +;; creating any threads if only one needs to run. + +;; Output via `download-printf` is pumped back to the original thread +;; so that it's not interleaved. Output is pumped while waiting on a +;; future or when creating one. + +(define MAX-PARALLEL 32) + +;; Only mutate a group or a future with the group's lock held + +(struct prefetch-group (custodian + [in-cleanup? #:mutable] + in-progress + lock + [pending #:mutable] + [pending-rev #:mutable] + [tokens #:mutable] + output)) + +(struct prefetch-future ([proc #:mutable] + [get-result #:mutable] + [evt #:mutable])) + +(struct output-msg (token fmt args)) + +(define (make-prefetch-group) + (prefetch-group (make-custodian) + #f + (make-hash) + (make-semaphore 1) + null + null + (for/list ([i (in-range MAX-PARALLEL)]) + i) + (make-async-channel))) + + +;; Ensure that `group` is terminated on exit from `thunk`. +;; Terminate only on the outer exit in case of nested calls. +(define (call-with-prefetch-cleanup group thunk) + (if (prefetch-group-in-cleanup? group) + (thunk) + (dynamic-wind + (lambda () + (set-prefetch-group-in-cleanup?! group #t)) + thunk + (lambda () + (custodian-shutdown-all (prefetch-group-custodian group)))))) + +;; Put `proc` in a future to be potentially run in a thread. +(define (make-prefetch-future group download-printf proc) + (pump-output group download-printf) + (define f (prefetch-future proc #t #f)) + (call-with-semaphore (prefetch-group-lock group) + (lambda () + (set-prefetch-group-pending-rev! group (cons f (prefetch-group-pending-rev group))) + (maybe-start-future group download-printf))) + (pump-output group download-printf) + f) + +;; Wait for a future to be ready +(define (prefetch-touch f group download-printf) + (pump-output group download-printf) + (cond + [(prefetch-future-evt f) + (pump-output group download-printf + #:evt (prefetch-future-evt f) + #:timeout #f) + ((prefetch-future-get-result f))] + [else + ((call-with-semaphore (prefetch-group-lock group) + (lambda () + (cond + [(prefetch-future-evt f) + ;; Got a thread meanwhile, so recur: + (lambda () + (prefetch-touch f group download-printf))] + [else + ;; Mark this future as no longer pending, and + ;; run its procedure directly: + (make-thread-proc f download-printf)]))))])) + +;; Wraps the procedure in `f` so that it's ready to run in a thread, +;; and replace the procured in `f` to eventually return the result +;; or propagate an exception. +(define (make-thread-proc f download-printf) + (define s (make-semaphore)) + (define proc (prefetch-future-proc f)) + (set-prefetch-future-proc! f #f) + (define result #f) + (define result-is-exn? #f) + (define (get-result) (if result-is-exn? + (raise result) + result)) + (set-prefetch-future-get-result! f get-result) + (set-prefetch-future-evt! f (semaphore-peek-evt s)) + (lambda () + (with-handlers ([values (lambda (v) + (set! result-is-exn? #t) + (set! result v))]) + (set! result (proc download-printf))) + (semaphore-post s) + (get-result))) + +;; Call with lock: +(define (maybe-start-future group download-printf) + (cond + [(null? (prefetch-group-pending group)) + (cond + [(null? (prefetch-group-pending-rev group)) + ;; Nothing to do + (void)] + [else + ;; Move reversed list to ready list + (set-prefetch-group-pending! group (reverse (prefetch-group-pending-rev group))) + (set-prefetch-group-pending-rev! group null) + (maybe-start-future group download-printf)])] + [(not (prefetch-future-proc (car (prefetch-group-pending group)))) + ;; Discard no-longer-needed future + (set-prefetch-group-pending! group (cdr (prefetch-group-pending group))) + (maybe-start-future group download-printf)] + [(and (null? (cdr (prefetch-group-pending group))) + (null? (prefetch-group-pending-rev group))) + ;; Only one prefetch available, so don't start a thread + (void)] + [(null? (prefetch-group-tokens group)) + ;; Too many running already + (void)] + [else + ;; Start a thread: + (define token (car (prefetch-group-tokens group))) + (set-prefetch-group-tokens! group (cdr (prefetch-group-tokens group))) + (define proc + (make-thread-proc (car (prefetch-group-pending group)) + (lambda (fmt . args) + (async-channel-put (prefetch-group-output group) + (output-msg token fmt args))))) + (set-prefetch-group-pending! group (cdr (prefetch-group-pending group))) + (parameterize ([current-custodian (prefetch-group-custodian group)]) + (thread + (lambda () + (proc) + ;; The future computation is done, so release the token and + ;; maybe start a new future: + (call-with-semaphore (prefetch-group-lock group) + (lambda () + (set-prefetch-group-tokens! group (cons token (prefetch-group-tokens group))) + (maybe-start-future group download-printf)))))) + (void)])) + +;; Check for output from a future thread: +(define (pump-output group + download-printf + #:evt [evt never-evt] + #:timeout [timeout 0]) + (sync/timeout + timeout + evt + (handle-evt (prefetch-group-output group) + (lambda (msg) + (define token (output-msg-token msg)) + (define fmt (output-msg-fmt msg)) + (define args (output-msg-args msg)) + (apply download-printf + (string-append + (format "~a~a: " + (if (token . < . 10) "0" "") + token) + fmt) + args) + (pump-output group + download-printf + #:evt evt + #:timeout timeout))))) diff --git a/racket/collects/pkg/private/stage.rkt b/racket/collects/pkg/private/stage.rkt index f62a5a578a..eceef6021b 100644 --- a/racket/collects/pkg/private/stage.rkt +++ b/racket/collects/pkg/private/stage.rkt @@ -28,7 +28,8 @@ "addl-installs.rkt" "repo-path.rkt" "orig-pkg.rkt" - "git.rkt") + "git.rkt" + "prefetch.rkt") (provide (struct-out install-info) remote-package-checksum @@ -48,16 +49,16 @@ (define (remote-package-checksum pkg download-printf pkg-name #:type [type #f] + #:prefetch? [prefetch? #f] + #:prefetch-group [prefetch-group #f] #:catalog-lookup-cache [catalog-lookup-cache #f] #:remote-checksum-cache [remote-checksum-cache #f]) - (cond - [(and remote-checksum-cache - (hash-ref remote-checksum-cache pkg #f)) - => (lambda (checksum) checksum)] - [else + (define (lookup-normally download-printf) (define checksum (match pkg [`(catalog ,pkg-name . ,_) + ;; If we're in a prefetch thread, we expect no other prefetchs in + ;; progress for `pkg-name`: (hash-ref (package-catalog-lookup pkg-name #f catalog-lookup-cache download-printf) 'checksum)] @@ -73,7 +74,38 @@ #:pkg-name pkg-name)])) (when remote-checksum-cache (hash-set! remote-checksum-cache pkg checksum)) - checksum])) + checksum) + + (when (and prefetch? (not (and catalog-lookup-cache + remote-checksum-cache + prefetch-group))) + (error "internal error: insufficient caches or group for prefetch of package checksum")) + + ;; Loop to combine cache lookup and prefetch dispatch: + (let loop ([prefetch? prefetch?] [download-printf download-printf]) + (cond + [(and remote-checksum-cache + (hash-ref remote-checksum-cache pkg #f)) + => (lambda (checksum) + (if (and (prefetch-future? checksum) + (not prefetch?)) + (prefetch-touch checksum prefetch-group download-printf) + checksum))] + [prefetch? + (define s (make-semaphore)) + (define f (make-prefetch-future + prefetch-group + download-printf + (lambda (download-printf) + ;; Don't start until hash table has future: + (semaphore-wait s) + ;; Adjusts cache when it has a result: + (lookup-normally download-printf)))) + (hash-set! remote-checksum-cache pkg f) + (semaphore-post s) + f] + [else + (lookup-normally download-printf)]))) ;; Downloads a package (if needed) and unpacks it (if needed) into a ;; temporary directory. From 58cc3e91c3dbf53bd6cedc1bdfc499b6cc352c6d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 10 Sep 2015 06:18:20 -0600 Subject: [PATCH 190/381] fix 32-bit Windows build for MSVC 2012 and up --- racket/src/worksp/libffi/libffi.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/worksp/libffi/libffi.vcxproj b/racket/src/worksp/libffi/libffi.vcxproj index 7c904451e0..4a95976bcd 100644 --- a/racket/src/worksp/libffi/libffi.vcxproj +++ b/racket/src/worksp/libffi/libffi.vcxproj @@ -125,7 +125,7 @@ cl.exe /EP /I . /I ../../foreign/libffi/src/x86 win32.asm > Release/win32_plain.asm -ml.exe /c /Cx /coff /Fo Release/win32.obj Release/win32_plain.asm +ml.exe /c /Cx /coff /safeseh /Fo Release/win32.obj Release/win32_plain.asm Release/win32.obj;%(Outputs) cl.exe /EP /I . /I ../../foreign/libffi/src/x86 win32.asm > x64/Release/win32_plain.asm @@ -133,7 +133,7 @@ ml64.exe /c /Cx /Fo x64/Release/win32.obj x64/Release/win32_plain.asm x64/Release/win32.obj;%(Outputs) cl.exe /EP /I . /I ../../foreign/libffi/src/x86 win32.asm > Release/win32_plain.asm -ml.exe /c /Cx /coff /Fo Release/win32.obj Release/win32_plain.asm +ml.exe /c /Cx /coff /safeseh /Fo Release/win32.obj Release/win32_plain.asm Release/win32.obj;%(Outputs) cl.exe /EP /I . /I ../../foreign/libffi/src/x86 win32.asm > x64/Release/win32_plain.asm From 24eb509d1520d50fc1ea9dc2b87bd04437a8bfe1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 10 Sep 2015 07:57:30 -0600 Subject: [PATCH 191/381] fix broken test Test added in 8ee717520f was broken, because it used `(current-milliseconds)` instead of `(current-ienxact-milliseconds)` to construct an argument to`alarm-evt`' --- pkgs/racket-test-core/tests/racket/sync.rktl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/sync.rktl b/pkgs/racket-test-core/tests/racket/sync.rktl index aeb6627bb0..c7d1220aef 100644 --- a/pkgs/racket-test-core/tests/racket/sync.rktl +++ b/pkgs/racket-test-core/tests/racket/sync.rktl @@ -1432,7 +1432,7 @@ (test val values got))) (try values 'ok-channel) - (try (lambda (c) (choice-evt c (alarm-evt (+ 10000 (current-milliseconds))))) + (try (lambda (c) (choice-evt c (alarm-evt (+ 10000 (current-inexact-milliseconds))))) 'ok-channel+alarm)) ;; ---------------------------------------- From bc929d4876710e7a1e9e699b4a6bb57a26551f42 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 10 Sep 2015 08:38:18 -0600 Subject: [PATCH 192/381] raco pkg install: more parallelism for catalog lookups The layer to handle Git repo clones triggers an early catalog lookup, so add prefetching there, too. --- racket/collects/pkg/private/catalog.rkt | 125 +++++++++++++-------- racket/collects/pkg/private/clone-path.rkt | 56 ++++++--- racket/collects/pkg/private/install.rkt | 21 ++-- racket/collects/pkg/private/prefetch.rkt | 18 +++ racket/collects/pkg/private/stage.rkt | 26 ++--- 5 files changed, 154 insertions(+), 92 deletions(-) diff --git a/racket/collects/pkg/private/catalog.rkt b/racket/collects/pkg/private/catalog.rkt index ebaabb1279..d95228212c 100644 --- a/racket/collects/pkg/private/catalog.rkt +++ b/racket/collects/pkg/private/catalog.rkt @@ -7,7 +7,8 @@ "../name.rkt" "params.rkt" "config.rkt" - "print.rkt") + "print.rkt" + "prefetch.rkt") (provide select-info-version source->relative-source @@ -127,58 +128,86 @@ ;; No further adjustments: new-ht))) -(define (package-catalog-lookup pkg details? cache download-printf) +(define (package-catalog-lookup pkg details? cache download-printf + #:prefetch? [prefetch? #f] + #:prefetch-group [prefetch-group #f]) + (define (lookup-normally download-printf) + (or (add-to-cache + pkg cache + (for/or ([i (in-list (pkg-catalogs))]) + (define (consulting-catalog suffix) + (if download-printf + (download-printf "Resolv~a ~s via ~a\n" suffix pkg (url->string i)) + (log-pkg-debug "consult~a catalog ~a" suffix (url->string i)))) + (source->absolute-source + i + (select-info-version + (catalog-dispatch + i + ;; Server: + (lambda (i) + (consulting-catalog "ing") + (define addr (add-version-query + (combine-url/relative i (format "pkg/~a" pkg)))) + (log-pkg-debug "resolving via ~a" (url->string addr)) + (read-from-server + 'package-catalog-lookup + addr + (lambda (v) (and (hash? v) + (for/and ([k (in-hash-keys v)]) + (symbol? k)))) + (lambda (s) #f))) + ;; Local database: + (lambda () + (define pkgs (db:get-pkgs #:name pkg)) + (and (pair? pkgs) + (begin + (consulting-catalog "ed") + (db-pkg-info (car pkgs) details?)))) + ;; Local directory: + (lambda (path) + (define pkg-path (build-path path "pkg" pkg)) + (and (file-exists? pkg-path) + (begin + (consulting-catalog "ed") + (call-with-input-file* pkg-path read))))))))) + (pkg-error (~a "cannot find package on catalogs\n" + " package: ~a") + pkg))) + (when (and details? cache) (error "internal error: catalog-lookup cache doesn't keep details")) + (or (and cache - (hash-ref cache pkg #f)) - (add-to-cache - pkg cache - (for/or ([i (in-list (pkg-catalogs))]) - (define (consulting-catalog suffix) - (if download-printf - (download-printf "Resolv~a ~s via ~a\n" suffix pkg (url->string i)) - (log-pkg-debug "consult~a catalog ~a" suffix (url->string i)))) - (source->absolute-source - i - (select-info-version - (catalog-dispatch - i - ;; Server: - (lambda (i) - (consulting-catalog "ing") - (define addr (add-version-query - (combine-url/relative i (format "pkg/~a" pkg)))) - (log-pkg-debug "resolving via ~a" (url->string addr)) - (read-from-server - 'package-catalog-lookup - addr - (lambda (v) (and (hash? v) - (for/and ([k (in-hash-keys v)]) - (symbol? k)))) - (lambda (s) #f))) - ;; Local database: - (lambda () - (define pkgs (db:get-pkgs #:name pkg)) - (and (pair? pkgs) - (begin - (consulting-catalog "ed") - (db-pkg-info (car pkgs) details?)))) - ;; Local directory: - (lambda (path) - (define pkg-path (build-path path "pkg" pkg)) - (and (file-exists? pkg-path) - (begin - (consulting-catalog "ed") - (call-with-input-file* pkg-path read))))))))) - (pkg-error (~a "cannot find package on catalogs\n" - " package: ~a") - pkg))) + (let ([v (hash-ref cache pkg #f)]) + (if (and (prefetch-future? v) + (not prefetch?)) + (prefetch-touch v prefetch-group download-printf) + v))) + (cond + [prefetch? + (make-prefetch-future/hash cache + pkg + lookup-normally + prefetch-group + download-printf)] + [else (lookup-normally download-printf)]))) -(define (package-catalog-lookup-source pkg cache download-printf) - (hash-ref (package-catalog-lookup pkg #f cache download-printf) - 'source)) +;; Beware that this function produces `#f` in prefetch mode when a +;; prefetch future is created or hasn't been touched. +(define (package-catalog-lookup-source pkg cache download-printf + #:prefetch? [prefetch? #f] + #:prefetch-group [prefetch-group #f]) + (define info (package-catalog-lookup pkg #f cache download-printf + #:prefetch? prefetch? + #:prefetch-group prefetch-group)) + (cond + [(and (prefetch-future? info) + (not prefetch?)) + (hash-ref (prefetch-touch info prefetch-group download-printf) 'source)] + [(prefetch-future? info) #f] + [else (hash-ref info 'source)])) (define (add-to-cache pkg cache v) (when (and cache v) diff --git a/racket/collects/pkg/private/clone-path.rkt b/racket/collects/pkg/private/clone-path.rkt index c6635fa9a6..32c37bcb53 100644 --- a/racket/collects/pkg/private/clone-path.rkt +++ b/racket/collects/pkg/private/clone-path.rkt @@ -51,7 +51,8 @@ catalog-lookup-cache download-printf from-command-line? - convert-to-non-clone?) + convert-to-non-clone? + prefetch-group) ;; A `repo-descs` is (hash repo (hash pkg-name desc) ...) (define (add-repo repo-descs repo name desc) (hash-set repo-descs repo @@ -60,18 +61,27 @@ desc))) ;; Filter `descs` to get get repo mappings + (define (add-repo-desc desc ht #:prefetch? [prefetch? #f]) + (cond + [(desc->name desc) + => (lambda (name) + (cond + [(desc->repo desc catalog-lookup-cache download-printf + #:prefetch? prefetch? + #:prefetch-group prefetch-group) + => (lambda (repo) + (if prefetch? + ht + (add-repo ht repo name desc)))] + [else ht]))] + [else ht])) + (when prefetch-group + (for ([desc (in-list descs)]) + (add-repo-desc desc (hash) #:prefetch? #t))) (define new-repo-descs (for/fold ([ht (hash)]) ([desc (in-list descs)]) - (cond - [(desc->name desc) - => (lambda (name) - (cond - [(desc->repo desc catalog-lookup-cache download-printf) - => (lambda (repo) - (add-repo ht repo name desc))] - [else ht]))] - [else ht]))) - + (add-repo-desc desc ht))) + ;; If updating, we don't want to complain about repos ;; whose repo status isn't changing. (define check-repo-descs @@ -353,8 +363,13 @@ ;; If `catalog-lookup-cache` is given, then check the catalog ;; if necessary to see whether the name resolves to a repository ;; (where the catalog will be used, anyway, so it's fine to -;; lookup now and cache the result) -(define (desc->repo d catalog-lookup-cache download-printf) +;; lookup now and cache the result). +;; In prefetch mode, the result is not useful (even as a prefetch +;; future), because no prefetch is set up for a recursive +;; resolution. +(define (desc->repo d catalog-lookup-cache download-printf + #:prefetch? [prefetch? #f] + #:prefetch-group [prefetch-group #f]) (define-values (name type) (package-source->name+type (pkg-desc-source d) (pkg-desc-type d))) @@ -365,10 +380,17 @@ [catalog-lookup-cache (define src (package-catalog-lookup-source name catalog-lookup-cache - download-printf)) - (desc->repo (pkg-desc src #f name #f #f #f) - catalog-lookup-cache - download-printf)] + download-printf + #:prefetch? prefetch? + #:prefetch-group prefetch-group)) + ;; Might be a prefetch future in prefetch mode, so continue + ;; only if possible: + (and (string? src) + (desc->repo (pkg-desc src #f name #f #f #f) + catalog-lookup-cache + download-printf + #:prefetch? prefetch? + #:prefetch-group prefetch-group))] [else #f])] [(git github clone) (define pkg-url (string->url (pkg-desc-source d))) diff --git a/racket/collects/pkg/private/install.rkt b/racket/collects/pkg/private/install.rkt index 4b6ff339a0..2df70b180d 100644 --- a/racket/collects/pkg/private/install.rkt +++ b/racket/collects/pkg/private/install.rkt @@ -884,19 +884,20 @@ force) (early-check-for-installed filtered-descs db #:wanted? #f)) - (define-values (new-descs done-descs done-infos clone-behavior repo-descs - extra-updating) - (adjust-to-normalize-repos filtered-descs old-descs old-infos - old-clone-behavior old-repo-descs - updating? - catalog-lookup-cache - download-printf - from-command-line? - convert-to-non-clone?)) - (call-with-prefetch-cleanup prefetch-group (lambda () + (define-values (new-descs done-descs done-infos clone-behavior repo-descs + extra-updating) + (adjust-to-normalize-repos filtered-descs old-descs old-infos + old-clone-behavior old-repo-descs + updating? + catalog-lookup-cache + download-printf + from-command-line? + convert-to-non-clone? + prefetch-group)) + (with-handlers* ([vector? (match-lambda [(vector updating? new-infos dep-pkg deps more-pre-succeed conv clone-info) diff --git a/racket/collects/pkg/private/prefetch.rkt b/racket/collects/pkg/private/prefetch.rkt index 4400d20e4e..77cb5fd812 100644 --- a/racket/collects/pkg/private/prefetch.rkt +++ b/racket/collects/pkg/private/prefetch.rkt @@ -5,6 +5,7 @@ prefetch-group-in-progress call-with-prefetch-cleanup make-prefetch-future + make-prefetch-future/hash prefetch-future? prefetch-touch) @@ -71,6 +72,23 @@ (pump-output group download-printf) f) +;; Like `make-prefetch-future`, but ensures a single prefetch for a +;; given key with respect to the given table, and install the new future +;; in that table. +(define (make-prefetch-future/hash table key proc group download-printf) + (define s (make-semaphore)) + (define f (make-prefetch-future + group + download-printf + (lambda (download-printf) + ;; Don't start until hash table has future: + (semaphore-wait s) + ;; Adjusts cache when it has a result: + (proc download-printf)))) + (hash-set! table key f) + (semaphore-post s) + f) + ;; Wait for a future to be ready (define (prefetch-touch f group download-printf) (pump-output group download-printf) diff --git a/racket/collects/pkg/private/stage.rkt b/racket/collects/pkg/private/stage.rkt index eceef6021b..d8c86a731a 100644 --- a/racket/collects/pkg/private/stage.rkt +++ b/racket/collects/pkg/private/stage.rkt @@ -57,11 +57,10 @@ (define checksum (match pkg [`(catalog ,pkg-name . ,_) - ;; If we're in a prefetch thread, we expect no other prefetchs in - ;; progress for `pkg-name`: - (hash-ref (package-catalog-lookup pkg-name #f catalog-lookup-cache - download-printf) - 'checksum)] + (define info (package-catalog-lookup pkg-name #f catalog-lookup-cache + download-printf + #:prefetch-group prefetch-group)) + (hash-ref info 'checksum)] [`(url ,pkg-url-str) (package-url->checksum pkg-url-str #:type type @@ -92,18 +91,11 @@ (prefetch-touch checksum prefetch-group download-printf) checksum))] [prefetch? - (define s (make-semaphore)) - (define f (make-prefetch-future - prefetch-group - download-printf - (lambda (download-printf) - ;; Don't start until hash table has future: - (semaphore-wait s) - ;; Adjusts cache when it has a result: - (lookup-normally download-printf)))) - (hash-set! remote-checksum-cache pkg f) - (semaphore-post s) - f] + (make-prefetch-future/hash remote-checksum-cache + pkg + lookup-normally + prefetch-group + download-printf)] [else (lookup-normally download-printf)]))) From 4c2a32d29301bc93f8429d2129d674b88f072369 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 10 Sep 2015 15:36:22 -0400 Subject: [PATCH 193/381] Document inspector of #f for make-struct-type --- pkgs/racket-doc/scribblings/reference/struct.scrbl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/struct.scrbl b/pkgs/racket-doc/scribblings/reference/struct.scrbl index 806703c1ba..ac5fe749e0 100644 --- a/pkgs/racket-doc/scribblings/reference/struct.scrbl +++ b/pkgs/racket-doc/scribblings/reference/struct.scrbl @@ -135,7 +135,8 @@ The @racket[inspector] argument normally controls access to reflective information about the structure type and its instances; see @secref["inspectors"] for more information. If @racket[inspector] is @racket['prefab], then the resulting @tech{prefab} structure type and -its instances are always transparent. +its instances are always transparent. If @racket[inspector] is +@racket[#f], then the structure type's instances are transparent. If @racket[proc-spec] is an integer or procedure, instances of the structure type act as procedures. See @racket[prop:procedure] for From 8d9eb0534728888c286e7ae77ce82149bd1ef482 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 10 Sep 2015 21:16:49 -0400 Subject: [PATCH 194/381] syntax/parse: accept #:context (list symbol/#f syntax) The symbol is used as the "who" field in the error message. Also fix lazy-require of runtime-report.rkt in residual.rkt; don't load until syntax-parse actually needs to produce an error report. (Previously was loaded to create handler whenever syntax-parse code ran.) --- .../syntax/scribblings/parse/parsing.scrbl | 25 ++++++++++++--- pkgs/racket-test/tests/stxparse/test.rkt | 31 ++++++++++++++----- racket/collects/syntax/parse/debug.rkt | 3 +- .../collects/syntax/parse/private/parse.rkt | 10 ++++-- .../syntax/parse/private/residual.rkt | 26 +++++++++++++++- .../syntax/parse/private/runtime-report.rkt | 30 +++++++++--------- racket/collects/unstable/error.rkt | 1 + 7 files changed, 92 insertions(+), 34 deletions(-) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl index 41d253c7e8..5f3d7d22a8 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl @@ -40,7 +40,8 @@ Two parsing forms are provided: @racket[syntax-parse] and (code:line #:phase phase-expr)] [clause (syntax-pattern pattern-directive ... body ...+)]) #:contracts ([stx-expr syntax?] - [context-expr syntax?] + [context-expr (or/c syntax? symbol? #f + (list/c symbol? syntax?))] [phase-expr (or/c exact-integer? #f)])]{ Evaluates @racket[stx-expr], which should produce a syntax object, and @@ -60,18 +61,32 @@ error is raised. The following options are supported: @specsubform[(code:line #:context context-expr) - #:contracts ([context-expr syntax?])]{ + #:contracts + ([context-expr (or/c syntax? symbol? #f + (list/c symbol? syntax?))])]{ When present, @racket[context-expr] is used in reporting parse -failures; otherwise @racket[stx-expr] is used. The -@racket[current-syntax-context] parameter is also set to the value of -@racket[context-expr]. +failures; otherwise @racket[stx-expr] is used. If +@racket[context-expr] evaluates to @racket[(list _who _context-stx)], +then @racket[_who] appears in the error message as the form raising +the error, and @racket[_context-stx] is used as the term. If +@racket[context-expr] evaluates to a symbol, it is used as +@racket[_who] and @racket[stx-expr] (the syntax to be destructured) is +used as @racket[_context-stx]. If @racket[context-expr] evaluates to a +syntax object, it is used as @racket[_context-stx] and @racket[_who] +is inferred as with @racket[raise-syntax-error]. + +The @racket[current-syntax-context] parameter is also set to the +syntax object @racket[_context-stx]. @(myexamples (syntax-parse #'(a b 3) [(x:id ...) 'ok]) (syntax-parse #'(a b 3) #:context #'(lambda (a b 3) (+ a b)) + [(x:id ...) 'ok]) + (syntax-parse #'(a b 3) + #:context 'check-id-list [(x:id ...) 'ok])) } diff --git a/pkgs/racket-test/tests/stxparse/test.rkt b/pkgs/racket-test/tests/stxparse/test.rkt index a1efa55ad5..d2e94dffcc 100644 --- a/pkgs/racket-test/tests/stxparse/test.rkt +++ b/pkgs/racket-test/tests/stxparse/test.rkt @@ -268,14 +268,29 @@ ;; == syntax-parse: other feature tests -(test-case "syntax-parse: #:context" - (check-exn - (lambda (exn) - (regexp-match #rx"me: expected exact-nonnegative-integer" (exn-message exn))) - (lambda () - (syntax-parse #'(m x) #:context #'me - [(_ n:nat) 'ok]))) - (void)) +(test-case "syntax-parse: #:context w/ syntax" + (check-exn + #rx"me: expected exact-nonnegative-integer" + (lambda () + (syntax-parse #'(m x) + #:context #'me + [(_ n:nat) 'ok])))) + +(test-case "syntax-parse: #:context w/ symbol" + (check-exn + #rx"me: expected identifier" + (lambda () + (syntax-parse #'(m 1) + #:context 'me + [(_ x:id) 'ok])))) + +(test-case "syntax-parse: #:context w/ symbol+stx" + (check-exn + #rx"me: expected identifier.*in: \\(bigterm\\)" + (lambda () + (syntax-parse #'(m 1) + #:context (list 'me #'(bigterm)) + [(_ x:id) 'ok])))) (test-case "syntax-parse: #:literals" (syntax-parse #'(0 + 1 * 2) diff --git a/racket/collects/syntax/parse/debug.rkt b/racket/collects/syntax/parse/debug.rkt index f24074a9ec..3b161f8f34 100644 --- a/racket/collects/syntax/parse/debug.rkt +++ b/racket/collects/syntax/parse/debug.rkt @@ -9,8 +9,7 @@ syntax/parse/private/residual "private/runtime.rkt" "private/runtime-progress.rkt" - (except-in "private/runtime-report.rkt" - syntax-patterns-fail) + "private/runtime-report.rkt" "private/kws.rkt") ;; No lazy loading for this module's dependencies. diff --git a/racket/collects/syntax/parse/private/parse.rkt b/racket/collects/syntax/parse/private/parse.rkt index 807a670856..ce2fe42f5c 100644 --- a/racket/collects/syntax/parse/private/parse.rkt +++ b/racket/collects/syntax/parse/private/parse.rkt @@ -361,6 +361,10 @@ Conventions: (with-disappeared-uses (with-txlifts (lambda () + (define who + (syntax-case #'ctx () + [(m . _) (identifier? #'m) #'m] + [_ 'syntax-parse])) (define-values (chunks clauses-stx) (parse-keyword-options #'clauses parse-directive-table #:context #'ctx @@ -403,13 +407,13 @@ Conventions: (for/lists (patterns body-exprs defs2s) ([clause (in-list (stx->list clauses-stx))]) (for-clause clause))) (with-syntax ([(def ...) (apply append (get-txlifts-as-definitions) defs defs2s)]) - #`(let* ([ctx0 #,context] - [pr (ps-empty x ctx0)] + #`(let* ([ctx0 (normalize-context '#,who #,context x)] + [pr (ps-empty x (cadr ctx0))] [es #f] [cx x] [fh0 (syntax-patterns-fail ctx0)]) def ... - (parameterize ((current-syntax-context ctx0)) + (parameterize ((current-syntax-context (cadr ctx0))) (with ([fail-handler fh0] [cut-prompt fh0]) #,(cond [(pair? patterns) diff --git a/racket/collects/syntax/parse/private/residual.rkt b/racket/collects/syntax/parse/private/residual.rkt index 6f54d45e99..1f71d3097e 100644 --- a/racket/collects/syntax/parse/private/residual.rkt +++ b/racket/collects/syntax/parse/private/residual.rkt @@ -65,6 +65,7 @@ name->too-few/once name->too-few name->too-many + normalize-context syntax-patterns-fail) ;; == from runtime.rkt @@ -241,9 +242,32 @@ ;; == parse.rkt +;; normalize-context : Symbol Any Syntax -> (list Symbol/#f Syntax) +(define (normalize-context who ctx stx) + (cond [(syntax? ctx) + (list #f ctx)] + [(symbol? ctx) + (list ctx stx)] + [(eq? ctx #f) + (list #f stx)] + [(and (list? ctx) + (= (length ctx) 2) + (or (symbol? (car ctx)) (eq? #f (car ctx))) + (syntax? (cadr ctx))) + ctx] + [else (error who "bad #:context argument\n expected: ~s\n given: ~e" + '(or/c syntax? symbol? #f (list/c (or/c symbol? #f) syntax?)) + ctx)])) + +;; == parse.rkt + (lazy-require ["runtime-report.rkt" - (syntax-patterns-fail)]) + (call-current-failure-handler ctx fs)]) + +;; syntax-patterns-fail : (list Symbol/#f Syntax) -> FailureSet -> (escapes) +(define ((syntax-patterns-fail ctx) fs) + (call-current-failure-handler ctx fs)) ;; == specialized ellipsis parser ;; returns (values 'ok attr-values) or (values 'fail failure) diff --git a/racket/collects/syntax/parse/private/runtime-report.rkt b/racket/collects/syntax/parse/private/runtime-report.rkt index 22007719eb..f397f13457 100644 --- a/racket/collects/syntax/parse/private/runtime-report.rkt +++ b/racket/collects/syntax/parse/private/runtime-report.rkt @@ -6,16 +6,13 @@ unstable/error syntax/srcloc "minimatch.rkt" - (except-in syntax/parse/private/residual - syntax-patterns-fail) + syntax/parse/private/residual "kws.rkt") -(provide syntax-patterns-fail +(provide call-current-failure-handler current-failure-handler maximal-failures - invert-ps - ps->stx+index - ) + ps->stx+index) #| TODO: given (expect:thing _ D _ R) and (expect:thing _ D _ #f), @@ -28,8 +25,8 @@ Note: there is a cyclic dependence between residual.rkt and this module, broken by a lazy-require of this module into residual.rkt |# -(define ((syntax-patterns-fail stx0) fs) - (call-with-values (lambda () ((current-failure-handler) stx0 fs)) +(define (call-current-failure-handler ctx fs) + (call-with-values (lambda () ((current-failure-handler) ctx fs)) (lambda vals (error 'current-failure-handler "current-failure-handler: did not escape, produced ~e" @@ -37,8 +34,8 @@ broken by a lazy-require of this module into residual.rkt ((1) (car vals)) (else (cons 'values vals))))))) -(define (default-failure-handler stx0 fs) - (report-failureset stx0 fs)) +(define (default-failure-handler ctx fs) + (report-failureset ctx fs)) (define current-failure-handler (make-parameter default-failure-handler)) @@ -57,11 +54,11 @@ special handling of failures like "unexpected term" make things more complicated. |# -;; report-failureset : stx FailureSet -> escapes -(define (report-failureset stx0 fs) +;; report-failureset : (list Symbol/#f Syntax) FailureSet -> escapes +(define (report-failureset ctx fs) (let* ([classes (maximal-failures fs)] [reports (apply append (map report/class classes))]) - (raise-syntax-error/reports stx0 reports))) + (raise-syntax-error/reports ctx reports))) ;; A Report is ;; - (report string (listof string) stx stx) @@ -175,12 +172,15 @@ complicated. ;; == Do Report == -(define (raise-syntax-error/reports stx0 reports) +(define (raise-syntax-error/reports ctx reports) (let* ([report (car reports)] [more? (pair? (cdr reports))] [message0 (report-message report)] - [context (report-context report)]) + [context (report-context report)] + [who (car ctx)] + [stx0 (cadr ctx)]) (raise-syntax-error* message0 stx0 (report-stx report) + #:who who #:within (report-within-stx report) '("parsing context" multi maybe) context '("note" maybe) (and more? "additional errors omitted")))) diff --git a/racket/collects/unstable/error.rkt b/racket/collects/unstable/error.rkt index 07c76edfa7..1dcd11e62e 100644 --- a/racket/collects/unstable/error.rkt +++ b/racket/collects/unstable/error.rkt @@ -38,6 +38,7 @@ TODO [raise-syntax-error* (->* [string? (or/c syntax? #f) (or/c syntax? #f)] [#:continued (or/c string? (listof string)) + #:who (or/c symbol? #f) #:within (or/c #f syntax?)] #:rest details-list/c any)] From 15271b673dbcade6172e8fec6b2ce866613c1d26 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 10 Sep 2015 16:17:19 -0600 Subject: [PATCH 195/381] GC: adjust fixup phase to not touch irrelevant page records This is another step toward making a minor collections independent of total allocation. --- racket/src/racket/gc2/newgc.c | 432 ++++++++++++++++------------------ racket/src/racket/gc2/newgc.h | 6 +- 2 files changed, 208 insertions(+), 230 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index ba710c56c9..d87272670d 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -220,10 +220,6 @@ static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { static void GCVERBOSEPAGE(NewGC *gc, const char *msg, mpage* page) { GCVERBOSEprintf(gc, "%s %p: %p %p %p\n", msg, gc, page, page->addr, (void*)((intptr_t)page->addr + real_page_size(page))); } -# ifdef KILLING_DEBUG -static void killing_debug(NewGC *gc, mpage *page, objhead *info); -static void fprintf_debug(NewGC *gc, mpage *page, const char *msg, objhead *info, FILE* file, int check); -# endif #else # define GCVERBOSEPAGE(gc, msg, page) /* EMPTY */ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { @@ -2791,8 +2787,8 @@ inline static int page_mmu_protectable(mpage *page) { static void set_has_back_pointers(NewGC *gc, mpage *page) { page->back_pointers = 1; - page->backpointer_next = gc->backpointer_next; - gc->backpointer_next = page; + page->modified_next = gc->modified_next; + gc->modified_next = page; } static int designate_modified_gc(NewGC *gc, void *p) @@ -3485,13 +3481,15 @@ void GC_mark2(const void *const_p, struct NewGC *gc) } #endif + GC_ASSERT(!page->marked_from); + /* MED OR BIG PAGE */ if (page->size_class) { /* BIG PAGE */ - if (page->size_class > 1) { + if (page->size_class > SIZE_CLASS_MED_PAGE) { /* This is a bigpage. The first thing we do is see if its been marked previously */ - if (page->size_class != 2) { + if (page->size_class != SIZE_CLASS_BIG_PAGE) { GCDEBUG((DEBUGOUTF, "Not marking %p on big %p (already marked)\n", p, page)); RELEASE_PAGE_LOCK(is_a_master_page, page); return; @@ -3503,7 +3501,13 @@ void GC_mark2(const void *const_p, struct NewGC *gc) if((page->generation == AGE_GEN_0) && !is_a_master_page) promote_marked_gen0_big_page(gc, page); + GC_ASSERT(!page->marked_on); page->marked_on = 1; + if (!is_a_master_page) { + page->modified_next = gc->modified_next; + gc->modified_next = page; + } + record_backtrace(gc, page, BIG_PAGE_TO_OBJECT(page)); GCDEBUG((DEBUGOUTF, "Marking %p on big page %p\n", p, page)); /* Finally, we want to add this to our mark queue, so we can @@ -3518,7 +3522,13 @@ void GC_mark2(const void *const_p, struct NewGC *gc) return; } info->mark = 1; - page->marked_on = 1; + if (!page->marked_on) { + page->marked_on = 1; + if (!is_a_master_page) { + page->modified_next = gc->modified_next; + gc->modified_next = page; + } + } p = OBJHEAD_TO_OBJPTR(info); backtrace_new_page_if_needed(gc, page); record_backtrace(gc, page, p); @@ -3546,7 +3556,13 @@ void GC_mark2(const void *const_p, struct NewGC *gc) if((NUM(page->addr) + page->previous_size) <= NUM(p)) { GCDEBUG((DEBUGOUTF, "Marking %p (leaving alone)\n", p)); ohead->mark = 1; - page->marked_on = 1; + if (!page->marked_on) { + page->marked_on = 1; + if (!is_a_master_page) { + page->modified_next = gc->modified_next; + gc->modified_next = page; + } + } page->previous_size = PREFIX_SIZE; page->live_size += ohead->size; record_backtrace(gc, page, p); @@ -3595,7 +3611,13 @@ void GC_mark2(const void *const_p, struct NewGC *gc) /* now either fetch where we're going to put this object or make a new page if we couldn't find a page with space to spare */ if (work) { - work->marked_on = 1; + if (!work->marked_on) { + work->marked_on = 1; + if (!work->marked_from) { + work->modified_next = gc->modified_next; + gc->modified_next = work; + } + } if (work->mprotected) { work->mprotected = 0; mmu_write_unprotect_page(gc->mmu, work->addr, APAGE_SIZE); @@ -3612,6 +3634,8 @@ void GC_mark2(const void *const_p, struct NewGC *gc) work->page_type = type; work->size = work->previous_size = PREFIX_SIZE; work->marked_on = 1; + work->modified_next = gc->modified_next; + gc->modified_next = work; backtrace_new_page(gc, work); work->next = gc->gen1_pages[type]; work->prev = NULL; @@ -4186,13 +4210,17 @@ static void reset_gen1_pages_live_and_previous_sizes(NewGC *gc) static void mark_backpointers(NewGC *gc) { + /* after this pass, the content of the `modified_next` chain is + pages that have `marked_from` set; additional pages are added + as they acquire `marked_on`, except master-GC pages */ + /* if this is not a full collection, then we need to mark any pointers that point backwards into generation 0, since they're roots. */ if (!gc->gc_full) { mpage *work; int traversed = 0; - for (work = gc->backpointer_next; work; work = work->backpointer_next) { + for (work = gc->modified_next; work; work = work->modified_next) { GC_ASSERT(work->back_pointers); if (work->mprotected) { @@ -4249,9 +4277,10 @@ static void mark_backpointers(NewGC *gc) gc->minor_old_traversed += traversed; gc->minor_old_skipped += (gc->num_gen1_pages - traversed); + } else { + /* reset modified chain, since we assume no kept pages up front */ + gc->modified_next = NULL; } - - gc->backpointer_next = NULL; } mpage *allocate_compact_target(NewGC *gc, mpage *work) @@ -4389,63 +4418,11 @@ inline static void do_heap_compact(NewGC *gc) } } -#ifdef KILLING_DEBUG -#include -static void fprintf_buffer(FILE* file, char* buf, int l) { - int i; - for (i=0; i < l; i++ ) { fprintf(file, "%02hhx",buf[i]); } - fprintf(file, "\n"); - for (i=0; i < l; i++ ) { - unsigned char c = buf[i]; - if(isprint(c)) { fprintf(file, "%c ", c); } - else { fprintf(file, " "); } - } - fprintf(file, "\n"); -} - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define INFO_SIZE_BYTES(info) ((info->size * WORD_SIZE) - sizeof(objhead)) -static void fprintf_debug(NewGC *gc, mpage *page, const char *msg, objhead *info, FILE* file, int check) { - Scheme_Object *obj = OBJHEAD_TO_OBJPTR(info); - fprintf(file, "%s obj %p ot %i it %i im %i is %i is >> 3 %i page %p pmo %i\n", msg, obj, obj->type, info->type, info->mark, info->size, info->size >> 3, page, page->marked_on); - switch (obj->type) { - case scheme_unix_path_type: - if (pagemap_find_page(gc->page_maps, MIN(SCHEME_PATH_VAL(obj), INFO_SIZE_BYTES(info)))) { - fprintf_buffer(file, SCHEME_PATH_VAL(obj), SCHEME_PATH_LEN(obj)); - } - else { - fprintf(file, "%p already freed and out of bounds\n", SCHEME_PATH_VAL(obj)); - } - break; - case scheme_symbol_type: - fprintf_buffer(file, SCHEME_SYM_VAL(obj), MIN(SCHEME_SYM_LEN(obj), INFO_SIZE_BYTES(info))); - break; - case scheme_resolved_module_path_type: - if (pagemap_find_page(gc->page_maps, SCHEME_PTR_VAL(obj))) { - /* - fprintf_debug(gc, page, "RMP ", OBJPTR_TO_OBJHEAD(SCHEME_PTR_VAL(obj)), file, check); - */ - } - else { - fprintf(file, "RMP %p already freed and out of bounds\n", SCHEME_PATH_VAL(obj)); - } - default: - fprintf_buffer(file, ((char *)obj), (info->size * WORD_SIZE) - sizeof(objhead)); - break; - } -} -static void killing_debug(NewGC *gc, mpage *page, objhead *info) { - fprintf_debug(gc, page, "killing", info, gcdebugOUT(gc), 1); -} -#endif - -static void repair_mixed_page(NewGC *gc, mpage *page, void **end, int track_back_pointers) +static void repair_mixed_page(NewGC *gc, mpage *page, void **end) { void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); Fixup2_Proc *fixup_table = gc->fixup_table; - gc->back_pointers = 0; - while (start <= end) { objhead *info = (objhead *)start; if (info->mark) { @@ -4494,191 +4471,190 @@ static void repair_mixed_page(NewGC *gc, mpage *page, void **end, int track_back abort(); } info->mark = 0; -#ifdef MZ_USE_PLACES - page->marked_from = 1; -#endif } else { -#ifdef KILLING_DEBUG - killing_debug(gc, page, info); -#endif info->dead = 1; start += info->size; } } - - if (track_back_pointers) { - if (gc->back_pointers) - set_has_back_pointers(gc, page); - else - page->back_pointers = 0; - } } -static void repair_heap(NewGC *gc) +static void chain_marked_on(NewGC *gc) +/* add any page that is marked on to the `modified_next` chain */ { mpage *page; int i, ty; - Fixup2_Proc *fixup_table = gc->fixup_table; + + gc->modified_next = NULL; for (i = 0; i < PAGE_TYPES; i++) { for (page = gc->gen1_pages[i]; page; page = page->next) { - if (page->marked_on || page->marked_from) { - page->has_new = 0; - gc->back_pointers = 0; - /* these are guaranteed not to be protected */ - if (page->size_class) { - /* since we get here via gen1_pages, it's a big page */ - void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); - void **end = PAGE_END_VSS(page); - - GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", - page, start)); - page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark */ - switch(page->page_type) { - case PAGE_TAGGED: - fixup_table[*(unsigned short*)start](start, gc); - break; - case PAGE_ATOMIC: break; - case PAGE_ARRAY: - while(start < end) gcFIXUP2(*(start++), gc); - break; - case PAGE_PAIR: - { - Scheme_Object *p = (Scheme_Object *)start; - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); - } - break; - case PAGE_TARRAY: - { - unsigned short tag = *(unsigned short *)start; - ASSERT_TAG(tag); - end -= INSET_WORDS; - while(start < end) start += fixup_table[tag](start, gc); - break; - } - } - } else { - void **start = PPTR(NUM(page->addr) + page->previous_size); - void **end = PAGE_END_VSS(page); - - GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", - page, start)); - switch(page->page_type) { - case PAGE_TAGGED: - while(start < end) { - objhead *info = (objhead *)start; - - if(info->mark) { - void *obj_start = OBJHEAD_TO_OBJPTR(start); - unsigned short tag = *(unsigned short *)obj_start; - ASSERT_TAG(tag); - info->mark = 0; - fixup_table[tag](obj_start, gc); - } else { - info->dead = 1; -#ifdef KILLING_DEBUG - killing_debug(gc, page, info); -#endif - } - start += info->size; - } - break; - case PAGE_ATOMIC: - while(start < end) { - objhead *info = (objhead *)start; - if(info->mark) { - info->mark = 0; - } else { - info->dead = 1; -#ifdef KILLING_DEBUG - killing_debug(gc, page, info); -#endif - } - start += info->size; - } - break; - case PAGE_ARRAY: - while(start < end) { - objhead *info = (objhead *)start; - size_t size = info->size; - if(info->mark) { - void **tempend = PPTR(info) + info->size; - start = OBJHEAD_TO_OBJPTR(start); - while(start < tempend) gcFIXUP2(*start++, gc); - info->mark = 0; - } else { - info->dead = 1; -#ifdef KILLING_DEBUG - killing_debug(gc, page, info); -#endif - start += size; - } - } - break; - case PAGE_TARRAY: - while(start < end) { - objhead *info = (objhead *)start; - size_t size = info->size; - if(info->mark) { - void **tempend = PPTR(info) + (info->size - INSET_WORDS); - unsigned short tag; - start = OBJHEAD_TO_OBJPTR(start); - tag = *(unsigned short*)start; - ASSERT_TAG(tag); - while(start < tempend) - start += fixup_table[tag](start, gc); - info->mark = 0; - start = PPTR(info) + size; - } else { - info->dead = 1; -#ifdef KILLING_DEBUG - killing_debug(gc, page, info); -#endif - start += size; - } - } - break; - case PAGE_PAIR: - while(start < end) { - objhead *info = (objhead *)start; - if(info->mark) { - Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); - info->mark = 0; - } else { - info->dead = 1; -#ifdef KILLING_DEBUG - killing_debug(gc, page, info); -#endif - } - start += PAIR_SIZE_IN_BYTES >> LOG_WORD_SIZE; - } - break; - } - } - - if (gc->back_pointers) - set_has_back_pointers(gc, page); - else - page->back_pointers = 0; - } else GCDEBUG((DEBUGOUTF,"Not Cleaning page %p\n", page)); + if (page->marked_on) { + page->modified_next = gc->modified_next; + gc->modified_next = page; + } } } for (ty = 0; ty < MED_PAGE_TYPES; ty++) { for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { for (page = gc->med_pages[ty][i]; page; page = page->next) { - if (page->marked_on || page->marked_from) - repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size), 1); + if (page->marked_on) { + page->modified_next = gc->modified_next; + gc->modified_next = page; + } } } } +} +static void repair_heap(NewGC *gc) +{ + mpage *page, *next; + Fixup2_Proc *fixup_table = gc->fixup_table; + + /* These pages are guaranteed not to be protected, because + they've been marked on or marked from. + In the process of repairing, we may mark pages as + containing backpointers, in which case the page is + re-added to the `modified_next` chain for a future GC. */ + + page = gc->modified_next; + gc->modified_next = NULL; + + for (; page; page = next) { + GC_ASSERT(page->marked_on || page->marked_from); + next = page->modified_next; + page->has_new = 0; + gc->back_pointers = 0; + if (page->size_class >= SIZE_CLASS_BIG_PAGE) { + void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); + void **end = PAGE_END_VSS(page); + + GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", + page, start)); + page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark */ + switch(page->page_type) { + case PAGE_TAGGED: + fixup_table[*(unsigned short*)start](start, gc); + break; + case PAGE_ATOMIC: break; + case PAGE_ARRAY: + while(start < end) gcFIXUP2(*(start++), gc); + break; + case PAGE_PAIR: + { + Scheme_Object *p = (Scheme_Object *)start; + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + } + break; + case PAGE_TARRAY: + { + unsigned short tag = *(unsigned short *)start; + ASSERT_TAG(tag); + end -= INSET_WORDS; + while(start < end) start += fixup_table[tag](start, gc); + break; + } + } + } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { + void **start = PPTR(NUM(page->addr) + page->previous_size); + void **end = PAGE_END_VSS(page); + + GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", + page, start)); + switch(page->page_type) { + case PAGE_TAGGED: + while(start < end) { + objhead *info = (objhead *)start; + + if(info->mark) { + void *obj_start = OBJHEAD_TO_OBJPTR(start); + unsigned short tag = *(unsigned short *)obj_start; + ASSERT_TAG(tag); + info->mark = 0; + fixup_table[tag](obj_start, gc); + } else + info->dead = 1; + start += info->size; + } + break; + case PAGE_ATOMIC: + while(start < end) { + objhead *info = (objhead *)start; + if(info->mark) + info->mark = 0; + else + info->dead = 1; + start += info->size; + } + break; + case PAGE_ARRAY: + while(start < end) { + objhead *info = (objhead *)start; + size_t size = info->size; + if(info->mark) { + void **tempend = PPTR(info) + info->size; + start = OBJHEAD_TO_OBJPTR(start); + while(start < tempend) gcFIXUP2(*start++, gc); + info->mark = 0; + } else { + info->dead = 1; + start += size; + } + } + break; + case PAGE_TARRAY: + while(start < end) { + objhead *info = (objhead *)start; + size_t size = info->size; + if(info->mark) { + void **tempend = PPTR(info) + (info->size - INSET_WORDS); + unsigned short tag; + start = OBJHEAD_TO_OBJPTR(start); + tag = *(unsigned short*)start; + ASSERT_TAG(tag); + while(start < tempend) + start += fixup_table[tag](start, gc); + info->mark = 0; + start = PPTR(info) + size; + } else { + info->dead = 1; + start += size; + } + } + break; + case PAGE_PAIR: + while(start < end) { + objhead *info = (objhead *)start; + if(info->mark) { + Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + info->mark = 0; + } else + info->dead = 1; + start += PAIR_SIZE_IN_BYTES >> LOG_WORD_SIZE; + } + break; + } + } else { + GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); + repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size)); + } + + /* If there was a reference to a generation 1/2 object, that's a + backpointer for the next GC: */ + if (gc->back_pointers) + set_has_back_pointers(gc, page); + else + page->back_pointers = 0; + } + + /* All gen-half pages count as modified: */ for (page = gc->gen_half.pages; page; page = page->next) { GC_ASSERT(page->generation == AGE_GEN_HALF); - repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1), 0); + repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1)); } } @@ -5163,6 +5139,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (premaster_or_place_gc(gc)) GC_fixup_variable_stack(GC_variable_stack, 0, get_stack_base(gc), NULL); TIME_STEP("reparied roots"); + if (gc->gc_full && postmaster_and_place_gc(gc)) + chain_marked_on(gc); repair_heap(gc); TIME_STEP("repaired"); clean_up_heap(gc); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 8b559a3924..097671f1c4 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -23,7 +23,7 @@ typedef struct mpage { #endif uintptr_t previous_size; /* for med page, place to search for available block; for jit nursery, allocated size */ uintptr_t size; /* big page size, med page element size, or nursery starting point */ - struct mpage *backpointer_next; + struct mpage *modified_next; /* next in chain of pages for backpointers, marks, etc. */ unsigned short live_size; unsigned char generation :2; unsigned char back_pointers :1; @@ -142,8 +142,8 @@ typedef struct NewGC { intptr_t num_gen1_pages; /* linked list of pages with back pointers to be traversed in a - minor collection: */ - struct mpage *backpointer_next; + minor collection, etc.: */ + struct mpage *modified_next; MarkSegment *mark_stack; From 50df879e7972f3bc34bb510d86e4189f62b418bc Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 10 Sep 2015 17:42:46 -0600 Subject: [PATCH 196/381] GC: adjust cleanup phase to not touch irrelevant page records Fixes the last place where a minor collection touched a record per allocated page. --- racket/src/racket/gc2/newgc.c | 123 +++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index d87272670d..af0f4faa74 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2003,6 +2003,7 @@ inline static void reset_nursery(NewGC *gc) inline static void move_gen_half_pages_to_old(NewGC *gc) { GC_ASSERT(!gc->gen_half.curr_alloc_page); + gc->memory_in_use -= gen_half_size_in_use(gc); gc->gen_half.old_pages = gc->gen_half.pages; gc->gen_half.pages = NULL; } @@ -3614,6 +3615,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) if (!work->marked_on) { work->marked_on = 1; if (!work->marked_from) { + gc->memory_in_use -= work->size; work->modified_next = gc->modified_next; gc->modified_next = work; } @@ -4210,12 +4212,18 @@ static void reset_gen1_pages_live_and_previous_sizes(NewGC *gc) static void mark_backpointers(NewGC *gc) { - /* after this pass, the content of the `modified_next` chain is - pages that have `marked_from` set; additional pages are added - as they acquire `marked_on`, except master-GC pages */ + /* For a minor collection, we need to mark any pointers that point + backwards into generation 0, since they're roots. + + After this pass, for a minor collection, the content of the + `modified_next` chain is pages that have `marked_from` set. + Additional pages are added as they acquire `marked_on`, except + master-GC pages. + + When a generation-1 page is added to the `modified_next` chain, + it's old size is deducted from `memory_is_use`, and its size will + be added back during the repair pahse. */ - /* if this is not a full collection, then we need to mark any pointers - that point backwards into generation 0, since they're roots. */ if (!gc->gc_full) { mpage *work; int traversed = 0; @@ -4234,6 +4242,7 @@ static void mark_backpointers(NewGC *gc) /* must be a big page */ work->size_class = SIZE_CLASS_BIG_PAGE_MARKED; push_ptr(gc, TAG_AS_BIG_PAGE_PTR(BIG_PAGE_TO_OBJECT(work))); + gc->memory_in_use -= work->size; } else if (work->size_class == SIZE_CLASS_SMALL_PAGE) { /* small page */ void **start = PAGE_START_VSS(work); @@ -4245,15 +4254,12 @@ static void mark_backpointers(NewGC *gc) objhead *info = (objhead *)start; if (!info->dead) { info->mark = 1; - /* This must be a push_ptr, and not a direct call to - internal_mark. This is because we need every object - in the older heap to be marked out of and noted as - marked before we do anything else */ push_ptr(gc, OBJHEAD_TO_OBJPTR(start)); } start += info->size; } work->previous_size = PREFIX_SIZE; + gc->memory_in_use -= work->size; } else { /* medium page */ void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); @@ -4265,11 +4271,12 @@ static void mark_backpointers(NewGC *gc) objhead *info = (objhead *)start; if (!info->dead) { info->mark = 1; - /* This must be a push_ptr (see above) */ push_ptr(gc, OBJHEAD_TO_OBJPTR(info)); } start += info->size; } + + gc->memory_in_use -= work->live_size; } traversed++; @@ -4418,10 +4425,11 @@ inline static void do_heap_compact(NewGC *gc) } } -static void repair_mixed_page(NewGC *gc, mpage *page, void **end) +static int repair_mixed_page(NewGC *gc, mpage *page, void **end) { void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); Fixup2_Proc *fixup_table = gc->fixup_table; + int non_dead = 0; while (start <= end) { objhead *info = (objhead *)start; @@ -4471,11 +4479,14 @@ static void repair_mixed_page(NewGC *gc, mpage *page, void **end) abort(); } info->mark = 0; + non_dead++; } else { info->dead = 1; start += info->size; } } + + return non_dead; } static void chain_marked_on(NewGC *gc) @@ -4509,6 +4520,7 @@ static void chain_marked_on(NewGC *gc) static void repair_heap(NewGC *gc) { + uintptr_t memory_in_use; mpage *page, *next; Fixup2_Proc *fixup_table = gc->fixup_table; @@ -4520,11 +4532,18 @@ static void repair_heap(NewGC *gc) page = gc->modified_next; gc->modified_next = NULL; + + memory_in_use = gc->memory_in_use; for (; page; page = next) { GC_ASSERT(page->marked_on || page->marked_from); next = page->modified_next; page->has_new = 0; + if (gc->gc_full) + page->marked_on = 1; + else + page->marked_on = 0; + page->marked_from = 0; gc->back_pointers = 0; if (page->size_class >= SIZE_CLASS_BIG_PAGE) { void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); @@ -4557,6 +4576,8 @@ static void repair_heap(NewGC *gc) break; } } + + memory_in_use += page->size; } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { void **start = PPTR(NUM(page->addr) + page->previous_size); void **end = PAGE_END_VSS(page); @@ -4638,9 +4659,21 @@ static void repair_heap(NewGC *gc) } break; } + + page->previous_size = page->size; + memory_in_use += page->size; } else { + int non_dead; GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); - repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size)); + non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size)); + page->live_size = (page->size * non_dead); + memory_in_use += page->live_size; + page->previous_size = PREFIX_SIZE; /* start next block search at the beginning */ + if (page->generation == AGE_GEN_0) { + /* Tell the clean-up phase to keep this one (even for a minor GC): */ + page->marked_on = 1; + GC_ASSERT(non_dead); /* otherwise, wouldn't have marked_on */ + } } /* If there was a reference to a generation 1/2 object, that's a @@ -4654,8 +4687,12 @@ static void repair_heap(NewGC *gc) /* All gen-half pages count as modified: */ for (page = gc->gen_half.pages; page; page = page->next) { GC_ASSERT(page->generation == AGE_GEN_HALF); - repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1)); + (void)repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1)); } + + memory_in_use += gen_half_size_in_use(gc); + memory_in_use = add_no_overflow(memory_in_use, gc->phantom_count); + gc->memory_in_use = memory_in_use; } static inline void gen1_free_mpage(PageMap pagemap, mpage *page) { @@ -4730,8 +4767,8 @@ static void clean_up_heap(NewGC *gc) gen0_free_big_pages(gc); - for(i = 0; i < PAGE_TYPES; i++) { - if (gc->gc_full) { + if (gc->gc_full) { + for (i = 0; i < PAGE_TYPES; i++) { mpage *work = gc->gen1_pages[i]; mpage *prev = NULL; while(work) { @@ -4746,80 +4783,54 @@ static void clean_up_heap(NewGC *gc) } else { GCVERBOSEPAGE(gc, "clean_up_heap BIG PAGE ALIVE", work); work->marked_on = 0; - work->marked_from = 0; - work->previous_size = work->size; memory_in_use += work->size; prev = work; } work = next; } - } else { - mpage *work; - for (work = gc->gen1_pages[i]; work; work = work->next) { - work->marked_on = 0; - work->marked_from = 0; - work->previous_size = work->size; - memory_in_use += work->size; - } } } + /* For medium pages, generation-0 pages will appear first in each + list, so for a mnior GC, we can stop whenever we find a + generation-1 page */ for (ty = 0; ty < MED_PAGE_TYPES; ty++) { for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { mpage *work; mpage *prev = NULL, *next; for (work = gc->med_pages[ty][i]; work; work = next) { + next = work->next; if (work->marked_on) { - void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); - void **end = PPTR(NUM(work->addr) + APAGE_SIZE - work->size); - int non_dead = 0; - - while(start <= end) { - objhead *info = (objhead *)start; - if (!info->dead) { - non_dead++; - } - start += info->size; - } - - GC_ASSERT(non_dead); /* otherwise, wouldn't have marked_on */ - - next = work->next; - work->live_size = (work->size * non_dead); - memory_in_use += work->live_size; - work->previous_size = PREFIX_SIZE; work->marked_on = 0; - work->marked_from = 0; + memory_in_use += work->live_size; work->generation = AGE_GEN_1; prev = work; } else if (gc->gc_full || (work->generation == AGE_GEN_0)) { /* Page wasn't touched in full GC, or gen-0 not touched, so we can free it. */ - next = work->next; if(prev) prev->next = next; else gc->med_pages[ty][i] = next; if(next) work->next->prev = prev; GCVERBOSEPAGE(gc, "Cleaning up MED NO MARKEDON", work); gen1_free_mpage(pagemap, work); --gc->num_gen1_pages; } else { - /* not marked during minor gc */ - memory_in_use += work->live_size; - work->previous_size = PREFIX_SIZE; - work->marked_from = 0; - next = work->next; - prev = work; + /* no more marked during minor gc */ + next = NULL; } } gc->med_freelist_pages[ty][i] = prev; } } - memory_in_use += gen_half_size_in_use(gc); + if (gc->gc_full) { + memory_in_use += gen_half_size_in_use(gc); - memory_in_use = add_no_overflow(memory_in_use, gc->phantom_count); + memory_in_use = add_no_overflow(memory_in_use, gc->phantom_count); + + gc->memory_in_use = memory_in_use; + } - gc->memory_in_use = memory_in_use; cleanup_vacated_pages(gc); } @@ -5032,6 +5043,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full) gc->phantom_count = 0; + else if (gc->memory_in_use > gc->phantom_count) { + /* added back in repair_heap(), after any adjustments from gen0 phantom bytes */ + gc->memory_in_use -= gc->phantom_count; + } gc->gen0_phantom_count = 0; TIME_INIT(); From c416db91c11e236521c9f4228fa374c1ecbaa0a4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 07:45:01 -0600 Subject: [PATCH 197/381] Fix shared-space marked-page chaining Fixes a problem with a4910716e4, and adjusts place-specific major GCs to use the already constructed chain instead of reconstructing it. --- racket/src/racket/gc2/newgc.c | 345 ++++++++++++++++++++-------------- 1 file changed, 203 insertions(+), 142 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index af0f4faa74..e049188185 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -84,7 +84,7 @@ enum { PAGE_PAIR = 4, PAGE_BIG = 5, /* the number of page types: */ - PAGE_TYPES = 6, + PAGE_TYPES = 6 }; enum { @@ -120,7 +120,8 @@ enum { enum { AGE_GEN_0 = 0, AGE_GEN_HALF = 1, - AGE_GEN_1 = 2 + AGE_GEN_1 = 2, + AGE_VACATED = 3 }; static const char *type_name[PAGE_TYPES] = { @@ -1678,12 +1679,12 @@ int GC_allocate_phantom_bytes(void *pb, intptr_t request_size_bytes) request_size_bytes = -request_size_bytes; if (gc->memory_in_use > request_size_bytes) gc->memory_in_use -= request_size_bytes; - if (!page || (page->generation != AGE_GEN_1)) { + if (!page || (page->generation < AGE_GEN_1)) { if (gc->gen0_phantom_count > request_size_bytes) gc->gen0_phantom_count -= request_size_bytes; } } else { - if (!page || (page->generation != AGE_GEN_1)) + if (!page || (page->generation < AGE_GEN_1)) gc->gen0_phantom_count = add_no_overflow(gc->gen0_phantom_count, request_size_bytes); gc->memory_in_use = add_no_overflow(gc->memory_in_use, request_size_bytes); } @@ -4301,6 +4302,8 @@ mpage *allocate_compact_target(NewGC *gc, mpage *work) npage->size_class = SIZE_CLASS_SMALL_PAGE; npage->page_type = work->page_type; npage->marked_on = 1; + npage->modified_next = gc->modified_next; + gc->modified_next = npage; backtrace_new_page(gc, npage); pagemap_add(gc->page_maps, npage); gc->num_gen1_pages++; @@ -4411,6 +4414,9 @@ inline static void do_heap_compact(NewGC *gc) /* push work onto gc->release_pages */ work->next = gc->release_pages; gc->release_pages = work; + /* Setting the generation causes `work` to be ignored + in the `modified_next` chain: */ + work->generation = AGE_VACATED; work = prev; } else { @@ -4490,7 +4496,9 @@ static int repair_mixed_page(NewGC *gc, mpage *page, void **end) } static void chain_marked_on(NewGC *gc) -/* add any page that is marked on to the `modified_next` chain */ +/* add any page that is marked on to the `modified_next` chain; this + is needed for a master GC, because the place GCs do not register + marked master pages in the master GC's `modified_next` chain */ { mpage *page; int i, ty; @@ -4499,6 +4507,7 @@ static void chain_marked_on(NewGC *gc) for (i = 0; i < PAGE_TYPES; i++) { for (page = gc->gen1_pages[i]; page; page = page->next) { + GC_ASSERT(!page->marked_from); if (page->marked_on) { page->modified_next = gc->modified_next; gc->modified_next = page; @@ -4509,6 +4518,7 @@ static void chain_marked_on(NewGC *gc) for (ty = 0; ty < MED_PAGE_TYPES; ty++) { for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { for (page = gc->med_pages[ty][i]; page; page = page->next) { + GC_ASSERT(!page->marked_from); if (page->marked_on) { page->modified_next = gc->modified_next; gc->modified_next = page; @@ -4518,6 +4528,51 @@ static void chain_marked_on(NewGC *gc) } } +#if 0 +# define CHECK_MARKED_ON_IN_MODIFIED_CHAIN +static void chain_marked_on_check(NewGC *gc) +{ + mpage *page, *xpage; + int i, ty, found = 0; + + for (i = 0; i < PAGE_TYPES; i++) { + for (page = gc->gen1_pages[i]; page; page = page->next) { + if (page->marked_on) { + for (xpage = gc->modified_next; xpage; xpage = xpage->modified_next) { + if (xpage == page) + break; + } + GC_ASSERT(xpage); + found++; + } + } + } + + for (ty = 0; ty < MED_PAGE_TYPES; ty++) { + for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { + for (page = gc->med_pages[ty][i]; page; page = page->next) { + if (page->marked_on) { + for (xpage = gc->modified_next; xpage; xpage = xpage->modified_next) { + if (xpage == page) + break; + } + GC_ASSERT(xpage); + found++; + } + } + } + } + + for (xpage = gc->modified_next; xpage; xpage = xpage->modified_next) { + if (xpage->generation < AGE_VACATED) + --found; + } + GC_ASSERT(!found); +} +#else +static void chain_marked_on_check(NewGC *gc) { } +#endif + static void repair_heap(NewGC *gc) { uintptr_t memory_in_use; @@ -4538,150 +4593,154 @@ static void repair_heap(NewGC *gc) for (; page; page = next) { GC_ASSERT(page->marked_on || page->marked_from); next = page->modified_next; - page->has_new = 0; - if (gc->gc_full) - page->marked_on = 1; - else - page->marked_on = 0; - page->marked_from = 0; - gc->back_pointers = 0; - if (page->size_class >= SIZE_CLASS_BIG_PAGE) { - void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); - void **end = PAGE_END_VSS(page); + if (page->generation == AGE_VACATED) { + /* this page will be released later */ + } else { + page->has_new = 0; + if (gc->gc_full) + page->marked_on = 1; + else + page->marked_on = 0; + page->marked_from = 0; + gc->back_pointers = 0; + if (page->size_class >= SIZE_CLASS_BIG_PAGE) { + void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); + void **end = PAGE_END_VSS(page); - GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", - page, start)); - page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark */ - switch(page->page_type) { - case PAGE_TAGGED: - fixup_table[*(unsigned short*)start](start, gc); - break; - case PAGE_ATOMIC: break; - case PAGE_ARRAY: - while(start < end) gcFIXUP2(*(start++), gc); - break; - case PAGE_PAIR: - { - Scheme_Object *p = (Scheme_Object *)start; - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); - } - break; - case PAGE_TARRAY: - { - unsigned short tag = *(unsigned short *)start; - ASSERT_TAG(tag); - end -= INSET_WORDS; - while(start < end) start += fixup_table[tag](start, gc); + GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", + page, start)); + page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark */ + switch(page->page_type) { + case PAGE_TAGGED: + fixup_table[*(unsigned short*)start](start, gc); break; - } - } - - memory_in_use += page->size; - } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { - void **start = PPTR(NUM(page->addr) + page->previous_size); - void **end = PAGE_END_VSS(page); - - GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", - page, start)); - switch(page->page_type) { - case PAGE_TAGGED: - while(start < end) { - objhead *info = (objhead *)start; - - if(info->mark) { - void *obj_start = OBJHEAD_TO_OBJPTR(start); - unsigned short tag = *(unsigned short *)obj_start; - ASSERT_TAG(tag); - info->mark = 0; - fixup_table[tag](obj_start, gc); - } else - info->dead = 1; - start += info->size; - } - break; - case PAGE_ATOMIC: - while(start < end) { - objhead *info = (objhead *)start; - if(info->mark) - info->mark = 0; - else - info->dead = 1; - start += info->size; - } - break; - case PAGE_ARRAY: - while(start < end) { - objhead *info = (objhead *)start; - size_t size = info->size; - if(info->mark) { - void **tempend = PPTR(info) + info->size; - start = OBJHEAD_TO_OBJPTR(start); - while(start < tempend) gcFIXUP2(*start++, gc); - info->mark = 0; - } else { - info->dead = 1; - start += size; - } - } - break; - case PAGE_TARRAY: - while(start < end) { - objhead *info = (objhead *)start; - size_t size = info->size; - if(info->mark) { - void **tempend = PPTR(info) + (info->size - INSET_WORDS); - unsigned short tag; - start = OBJHEAD_TO_OBJPTR(start); - tag = *(unsigned short*)start; - ASSERT_TAG(tag); - while(start < tempend) - start += fixup_table[tag](start, gc); - info->mark = 0; - start = PPTR(info) + size; - } else { - info->dead = 1; - start += size; - } - } - break; - case PAGE_PAIR: - while(start < end) { - objhead *info = (objhead *)start; - if(info->mark) { - Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); + case PAGE_ATOMIC: break; + case PAGE_ARRAY: + while(start < end) gcFIXUP2(*(start++), gc); + break; + case PAGE_PAIR: + { + Scheme_Object *p = (Scheme_Object *)start; gcFIXUP2(SCHEME_CAR(p), gc); gcFIXUP2(SCHEME_CDR(p), gc); - info->mark = 0; - } else - info->dead = 1; - start += PAIR_SIZE_IN_BYTES >> LOG_WORD_SIZE; + } + break; + case PAGE_TARRAY: + { + unsigned short tag = *(unsigned short *)start; + ASSERT_TAG(tag); + end -= INSET_WORDS; + while(start < end) start += fixup_table[tag](start, gc); + break; + } + } + + memory_in_use += page->size; + } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { + void **start = PPTR(NUM(page->addr) + page->previous_size); + void **end = PAGE_END_VSS(page); + + GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", + page, start)); + switch(page->page_type) { + case PAGE_TAGGED: + while(start < end) { + objhead *info = (objhead *)start; + + if(info->mark) { + void *obj_start = OBJHEAD_TO_OBJPTR(start); + unsigned short tag = *(unsigned short *)obj_start; + ASSERT_TAG(tag); + info->mark = 0; + fixup_table[tag](obj_start, gc); + } else + info->dead = 1; + start += info->size; + } + break; + case PAGE_ATOMIC: + while(start < end) { + objhead *info = (objhead *)start; + if(info->mark) + info->mark = 0; + else + info->dead = 1; + start += info->size; + } + break; + case PAGE_ARRAY: + while(start < end) { + objhead *info = (objhead *)start; + size_t size = info->size; + if(info->mark) { + void **tempend = PPTR(info) + info->size; + start = OBJHEAD_TO_OBJPTR(start); + while(start < tempend) gcFIXUP2(*start++, gc); + info->mark = 0; + } else { + info->dead = 1; + start += size; + } + } + break; + case PAGE_TARRAY: + while(start < end) { + objhead *info = (objhead *)start; + size_t size = info->size; + if(info->mark) { + void **tempend = PPTR(info) + (info->size - INSET_WORDS); + unsigned short tag; + start = OBJHEAD_TO_OBJPTR(start); + tag = *(unsigned short*)start; + ASSERT_TAG(tag); + while(start < tempend) + start += fixup_table[tag](start, gc); + info->mark = 0; + start = PPTR(info) + size; + } else { + info->dead = 1; + start += size; + } + } + break; + case PAGE_PAIR: + while(start < end) { + objhead *info = (objhead *)start; + if(info->mark) { + Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + info->mark = 0; + } else + info->dead = 1; + start += PAIR_SIZE_IN_BYTES >> LOG_WORD_SIZE; + } + break; + } + + page->previous_size = page->size; + memory_in_use += page->size; + } else { + int non_dead; + GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); + non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size)); + page->live_size = (page->size * non_dead); + memory_in_use += page->live_size; + page->previous_size = PREFIX_SIZE; /* start next block search at the beginning */ + if (page->generation == AGE_GEN_0) { + /* Tell the clean-up phase to keep this one (even for a minor GC): */ + page->marked_on = 1; + GC_ASSERT(non_dead); /* otherwise, wouldn't have marked_on */ } - break; } - page->previous_size = page->size; - memory_in_use += page->size; - } else { - int non_dead; - GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); - non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size)); - page->live_size = (page->size * non_dead); - memory_in_use += page->live_size; - page->previous_size = PREFIX_SIZE; /* start next block search at the beginning */ - if (page->generation == AGE_GEN_0) { - /* Tell the clean-up phase to keep this one (even for a minor GC): */ - page->marked_on = 1; - GC_ASSERT(non_dead); /* otherwise, wouldn't have marked_on */ - } + /* If there was a reference to a generation 1/2 object, that's a + backpointer for the next GC: */ + if (gc->back_pointers) + set_has_back_pointers(gc, page); + else + page->back_pointers = 0; } - - /* If there was a reference to a generation 1/2 object, that's a - backpointer for the next GC: */ - if (gc->back_pointers) - set_has_back_pointers(gc, page); - else - page->back_pointers = 0; } /* All gen-half pages count as modified: */ @@ -5154,8 +5213,10 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (premaster_or_place_gc(gc)) GC_fixup_variable_stack(GC_variable_stack, 0, get_stack_base(gc), NULL); TIME_STEP("reparied roots"); - if (gc->gc_full && postmaster_and_place_gc(gc)) + if (gc->gc_full && postmaster_and_master_gc(gc)) chain_marked_on(gc); + else if (gc->gc_full) + chain_marked_on_check(gc); repair_heap(gc); TIME_STEP("repaired"); clean_up_heap(gc); From 81ee1b39c7943b6392a2443df7498cf73f6e33c8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 10:11:00 -0600 Subject: [PATCH 198/381] change the (relatively new) argument to `collect-garbage` Make the argument a symbol, 'major or 'minor, instead of a boolean, because that allows further extension. --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/memory.scrbl | 18 +++++++++++------- pkgs/racket-test-core/tests/racket/will.rktl | 4 ++++ racket/src/racket/src/schvers.h | 4 ++-- racket/src/racket/src/thread.c | 16 +++++++++++++--- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 79d570eae9..84ea116d61 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.16") +(define version "6.2.900.17") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/reference/memory.scrbl b/pkgs/racket-doc/scribblings/reference/memory.scrbl index ccee0c33a4..d67ca8bcf9 100644 --- a/pkgs/racket-doc/scribblings/reference/memory.scrbl +++ b/pkgs/racket-doc/scribblings/reference/memory.scrbl @@ -287,24 +287,28 @@ collection mode, the text has the format ]} -@defproc[(collect-garbage [minor? any/c #f]) void?]{ +@defproc[(collect-garbage [request (or/c 'major 'minor) 'major]) void?]{ Forces an immediate @tech{garbage collection} (unless garbage collection is disabled by setting @envvar{PLTDISABLEGC}). Some effectively unreachable data may remain uncollected, because the collector cannot prove that it is unreachable. -If @racket[minor?] is false, then a major collection is -run. Otherwise, a minor collection is run or no collection is run. (No +The @racket[collect-garbage] procedure provides some control over the +timing of collections, but garbage will obviously be collected even if +this procedure is never called (unless garbage collection is disabled). + +If @racket[request] is @racket['major], then a major collection is +run. If @racket[request] is @racket['minor], then either a minor +collection is run or no collection is run (and no collection occurs when @racket[(system-type 'gc)] returns @racket['cgc] or when a normally scheduled minor collection would -cause a major collection.) Minor collections run by +cause a major collection); minor collections triggered by @racket[collect-garbage] do not cause major collections to run any sooner than they would have otherwise. -The @racket[collect-garbage] procedure provides some control over the -timing of collections, but garbage will obviously be collected even if -this procedure is never called (unless garbage collection is disabled).} +@history[#:changed "6.2.900.17" @elem{Added the @racket[request] argument.}]} + @defproc[(current-memory-use [cust custodian? #f]) exact-nonnegative-integer?]{ diff --git a/pkgs/racket-test-core/tests/racket/will.rktl b/pkgs/racket-test-core/tests/racket/will.rktl index ecf0e333b0..a10573e4cc 100644 --- a/pkgs/racket-test-core/tests/racket/will.rktl +++ b/pkgs/racket-test-core/tests/racket/will.rktl @@ -3,6 +3,10 @@ (Section 'wills) +(collect-garbage 'major) +(collect-garbage 'minor) +(err/rt-test (collect-garbage 'other)) + (test #t exact-nonnegative-integer? (current-memory-use)) (test #t exact-nonnegative-integer? (current-memory-use #f)) (test #t exact-nonnegative-integer? (current-memory-use (current-custodian))) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index f7913d2faa..5aec9b8b28 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.16" +#define MZSCHEME_VERSION "6.2.900.17" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 16 +#define MZSCHEME_VERSION_W 17 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 7ef4c0db43..0ff1b3da06 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -243,6 +243,7 @@ THREAD_LOCAL_DECL(struct Scheme_GC_Pre_Post_Callback_Desc *gc_prepost_callback_d ROSYM static Scheme_Object *read_symbol, *write_symbol, *execute_symbol, *delete_symbol, *exists_symbol; ROSYM static Scheme_Object *client_symbol, *server_symbol; +ROSYM static Scheme_Object *major_symbol, *minor_symbol; THREAD_LOCAL_DECL(static int do_atomic = 0); THREAD_LOCAL_DECL(static int missed_context_switch = 0); @@ -520,7 +521,12 @@ void scheme_init_thread(Scheme_Env *env) exists_symbol = scheme_intern_symbol("exists"); client_symbol = scheme_intern_symbol("client"); server_symbol = scheme_intern_symbol("server"); - + + REGISTER_SO(major_symbol); + REGISTER_SO(minor_symbol); + major_symbol = scheme_intern_symbol("major"); + minor_symbol = scheme_intern_symbol("minor"); + GLOBAL_PRIM_W_ARITY("dump-memory-stats" , scheme_dump_gc_stats, 0, -1, env); GLOBAL_PRIM_W_ARITY("vector-set-performance-stats!", current_stats , 1, 2, env); @@ -713,10 +719,14 @@ void scheme_init_paramz(Scheme_Env *env) static Scheme_Object *collect_garbage(int argc, Scheme_Object *argv[]) { - if (argc == 1 && !SCHEME_FALSEP(argv[0])) { + if (argc == 1 && SAME_OBJ(minor_symbol, argv[0])) { scheme_collect_garbage_minor(); - } else { + } else if ((argc < 1) || SAME_OBJ(major_symbol, argv[0])) { scheme_collect_garbage(); + } else { + scheme_wrong_contract("collect-garbage", + "(or/c 'major 'minor)", + 0, argc, argv); } return scheme_void; From 52aa11c4074041b2cfb4628b7c960c79419e3104 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 7 Sep 2015 14:08:55 -0400 Subject: [PATCH 199/381] Propagate object inspectors in class/c wrappers This makes reflection work on an instance of a contracted class in the same way that it does on the original class. --- .../tests/racket/contract/class.rkt | 51 ++++++++++++++++++- .../collects/racket/private/class-c-old.rkt | 12 +++-- .../racket/private/class-internal.rkt | 7 ++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/class.rkt b/pkgs/racket-test/tests/racket/contract/class.rkt index 26fd95fc4b..e1f74313c4 100644 --- a/pkgs/racket-test/tests/racket/contract/class.rkt +++ b/pkgs/racket-test/tests/racket/contract/class.rkt @@ -2566,4 +2566,53 @@ (class object% (super-new) (define/public (callback f) (f 1)))) - promised-produced?))) + promised-produced?)) + + ;; Tests for reflection and class contracts + (test/spec-passed/result + 'reflection-1 + '(format "~a" + (new (contract (class/c) + (let ([x% + (class object% + (super-new) + (inspect #f) + (init-field [x 0]))]) + x%) + 'pos 'neg))) + "#(struct:object:x% 0)") + + (test/spec-passed/result + 'reflection-2 + '(format "~a" + (new (contract (class/c) + (let ([x% + (class object% + (super-new) + (init-field [x 0]))]) + x%) + 'pos 'neg))) + "#(struct:object:x% ...)") + + (test/spec-passed/result + 'equality-1 + '(let ([c% + (contract (class/c) + (class object% + (super-new) + (inspect #f) + (init-field [x 0])) + 'pos 'neg)]) + (equal? (new c%) (new c%))) + #t) + + (test/spec-passed/result + 'equality-2 + '(let ([c% + (contract (class/c) + (class object% + (super-new) + (init-field [x 0])) + 'pos 'neg)]) + (equal? (new c%) (new c%))) + #f)) diff --git a/racket/collects/racket/private/class-c-old.rkt b/racket/collects/racket/private/class-c-old.rkt index c9cd1dc297..cb2a2be7f7 100644 --- a/racket/collects/racket/private/class-c-old.rkt +++ b/racket/collects/racket/private/class-c-old.rkt @@ -213,6 +213,7 @@ supers (class-self-interface cls) void ;; No inspecting + (class-obj-inspector cls) ; inherit object inspector method-width method-ht @@ -273,7 +274,8 @@ 0 ;; No new fields in this class replacement undefined ;; Map object property to class: - (list (cons prop:object c)))]) + (list (cons prop:object c)) + (class-obj-inspector cls))]) (set-class-struct:object! c struct:object) (set-class-object?! c object?) (set-class-make-object! c object-make) @@ -480,6 +482,7 @@ supers (class-self-interface cls) void ;; No inspecting + (class-obj-inspector cls) method-width method-ht @@ -542,7 +545,8 @@ 0 ;; No new fields in this class replacement undefined ;; Map object property to class: - (list (cons prop:object c)))]) + (list (cons prop:object c)) + (class-obj-inspector cls))]) (set-class-struct:object! c struct:object) (set-class-object?! c object?) (set-class-make-object! c object-make) @@ -1544,6 +1548,7 @@ (list->vector (vector->list (class-supers cls))) (class-self-interface cls) void ;; No inspecting + (class-obj-inspector cls) method-width method-ht @@ -1603,7 +1608,8 @@ 0 ;; No new fields in this class replacement undefined ;; Map object property to class: - (list (cons prop:object c)))]) + (list (cons prop:object c)) + (class-obj-inspector cls))]) (set-class-struct:object! c struct:object) (set-class-object?! c object?) (set-class-make-object! c object-make) diff --git a/racket/collects/racket/private/class-internal.rkt b/racket/collects/racket/private/class-internal.rkt index 81958da49b..083f7c9589 100644 --- a/racket/collects/racket/private/class-internal.rkt +++ b/racket/collects/racket/private/class-internal.rkt @@ -1996,6 +1996,7 @@ pos supers ; pos is subclass depth, supers is vector self-interface ; self interface insp-mk ; dummy struct maker to control inspection access + obj-inspector ; the inspector used for instances of this class method-width ; total number of methods method-ht ; maps public names to vector positions @@ -2371,6 +2372,7 @@ last few projections. i (let-values ([(struct: make- ? -ref -set) (make-struct-type 'insp #f 0 0 #f null inspector)]) make-) + inspector method-width method-ht method-names remaining-abstract-names (interfaces->contracted-methods (list i)) #f @@ -3261,6 +3263,7 @@ An example 0 (vector #f) object<%> void ; never inspectable + #f ; this is for the inspector on the object 0 (make-hasheq) null null null #f @@ -3411,6 +3414,7 @@ An example (list->vector (vector->list (class-supers cls))) (class-self-interface cls) void ;; No inspecting + (class-obj-inspector cls) method-width method-ht @@ -3462,7 +3466,8 @@ An example 0 ;; No new fields in this class replacement unsafe-undefined ;; Map object property to class: - (list (cons prop:object c)))]) + (list (cons prop:object c)) + (class-obj-inspector cls))]) (set-class-struct:object! c struct:object) (set-class-object?! c object?) (set-class-make-object! c object-make) From 808a6ca2662bcf0a29a5a2d25d8d52cbf18389a6 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 11 Sep 2015 16:16:51 -0400 Subject: [PATCH 200/381] syntax/parse: remove ref to raise-syntax-error* Copy and specialize raise-syntax-error*. Also, taint the stxs in the exn raised. --- .../syntax/parse/private/runtime-report.rkt | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/racket/collects/syntax/parse/private/runtime-report.rkt b/racket/collects/syntax/parse/private/runtime-report.rkt index f397f13457..0cd3ad2f0a 100644 --- a/racket/collects/syntax/parse/private/runtime-report.rkt +++ b/racket/collects/syntax/parse/private/runtime-report.rkt @@ -58,7 +58,7 @@ complicated. (define (report-failureset ctx fs) (let* ([classes (maximal-failures fs)] [reports (apply append (map report/class classes))]) - (raise-syntax-error/reports ctx reports))) + (error/reports ctx reports))) ;; A Report is ;; - (report string (listof string) stx stx) @@ -172,18 +172,45 @@ complicated. ;; == Do Report == -(define (raise-syntax-error/reports ctx reports) - (let* ([report (car reports)] - [more? (pair? (cdr reports))] - [message0 (report-message report)] +(define (error/reports ctx reports) + (error/report ctx (car reports) (pair? (cdr reports)))) + +(define (error/report ctx report more?) + (let* ([message (report-message report)] [context (report-context report)] - [who (car ctx)] - [stx0 (cadr ctx)]) - (raise-syntax-error* message0 stx0 (report-stx report) - #:who who - #:within (report-within-stx report) - '("parsing context" multi maybe) context - '("note" maybe) (and more? "additional errors omitted")))) + [stx (cadr ctx)] + [who (or (car ctx) (infer-who stx))] + [sub-stx (report-stx report)] + [within-stx (report-within-stx report)] + [message + (compose-error-message + who message + '("at" maybe) (stx-if-loc sub-stx) + '("within" maybe) (stx-if-loc within-stx) + '("in" maybe) (stx-if-loc stx) + '("parsing context" multi maybe) context + '("note" maybe) (and more? "additional errors omitted"))] + [message + (if (error-print-source-location) + (let ([source-stx (or stx sub-stx within-stx)]) + (string-append (source-location->prefix source-stx) message)) + message)]) + (raise + (exn:fail:syntax message (current-continuation-marks) + (map syntax-taint + (cond [within-stx (list within-stx)] + [sub-stx (list sub-stx)] + [stx (list stx)] + [else null])))))) + +(define (stx-if-loc stx) + (and (syntax? stx) + (error-print-source-location) + (format "~.s" (syntax->datum stx)))) + +(define (infer-who stx) + (let* ([maybe-id (if (stx-pair? stx) (stx-car stx) stx)]) + (if (identifier? maybe-id) (syntax-e maybe-id) '?))) ;; ==== From 4f5c54db542e70db1973f6f8f1402d892f79d658 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 11 Sep 2015 17:19:07 -0400 Subject: [PATCH 201/381] syntax/parse: fix use of evaluators in docs --- .../syntax/scribblings/parse/define.scrbl | 7 +- .../syntax/scribblings/parse/ex-exprc.scrbl | 6 +- .../syntax/scribblings/parse/ex-kw-args.scrbl | 10 ++- .../scribblings/parse/ex-many-kws.scrbl | 6 +- .../parse/ex-mods-stxclasses.scrbl | 12 ++- .../scribblings/parse/experimental.scrbl | 8 +- .../syntax/scribblings/parse/intro.scrbl | 54 +++++++------ .../syntax/scribblings/parse/litconv.scrbl | 18 +++-- .../syntax/scribblings/parse/parse-common.rkt | 75 ++++++++++--------- .../syntax/scribblings/parse/parsing.scrbl | 27 ++++--- .../syntax/scribblings/parse/patterns.scrbl | 56 +++++++------- .../syntax/scribblings/parse/stxclasses.scrbl | 16 ++-- 12 files changed, 174 insertions(+), 121 deletions(-) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/define.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/define.scrbl index d04bbda69c..ff8e6f3b6e 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/define.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/define.scrbl @@ -6,6 +6,8 @@ "parse-common.rkt" (for-label syntax/parse/define)) +@(define the-eval (make-sp-eval)) + @title{Defining Simple Macros} @defmodule[syntax/parse/define] @@ -22,7 +24,7 @@ Defines a macro named @racket[macro-id]; equivalent to the following: ] @(the-eval '(require syntax/parse/define)) -@myexamples[ +@examples[#:eval the-eval (define-simple-macro (fn x:id rhs:expr) (lambda (x) rhs)) ((fn x x) 17) (fn 1 2) @@ -47,7 +49,7 @@ Defines a macro named @racket[macro-id]; equivalent to: (syntax-parser parse-option ... clause ...)) ] -@myexamples[ +@examples[#:eval the-eval (define-syntax-parser fn3 [(fn3 x:id rhs:expr) #'(lambda (x) rhs)] @@ -59,3 +61,4 @@ Defines a macro named @racket[macro-id]; equivalent to: (fn3 a #:b 'c) ]} +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/ex-exprc.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/ex-exprc.scrbl index 241b49408e..366d60a893 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/ex-exprc.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/ex-exprc.scrbl @@ -6,6 +6,8 @@ "parse-common.rkt" (for-label racket/class)) +@(define the-eval (make-sp-eval)) + @title[#:tag "exprc"]{Contracts on Macro Sub-expressions} Just as procedures often expect certain kinds of values as arguments, @@ -17,7 +19,7 @@ For example, here is a macro @racket[myparameterize] that behaves like @racket[parameterize] but enforces the @racket[parameter?] contract on the parameter expressions. -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (myparameterize stx) (syntax-parse stx [(_ ((p v:expr) ...) body:expr) @@ -37,3 +39,5 @@ template, the expansion would have used the raw, unchecked expressions. The @racket[expr/c] syntax class does not change how pattern variables are bound; it only computes an attribute that represents the checked expression. + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/ex-kw-args.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/ex-kw-args.scrbl index 1dd03b73a0..e1089b0b0b 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/ex-kw-args.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/ex-kw-args.scrbl @@ -6,6 +6,8 @@ "parse-common.rkt" (for-label racket/class)) +@(define the-eval (make-sp-eval)) + @title{Optional Keyword Arguments} This section explains how to write a macro that accepts (simple) @@ -22,7 +24,7 @@ head-pattern forms are @racket[~seq], @racket[~or], and Here's one way to do it: -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mycond stx) (syntax-parse stx [(mycond (~or (~seq #:error-on-fallthrough who:expr) (~seq)) @@ -47,7 +49,7 @@ argument is omitted. Instead we must write @racket[(attribute who)], which produces @racket[#f] if matching did not assign a value to the attribute. -@myinteraction[ +@interaction[#:eval the-eval (mycond [(even? 13) 'blue] [(odd? 4) 'red]) (mycond #:error-on-fallthrough 'myfun @@ -62,7 +64,7 @@ There's a simpler way of writing the @racket[~or] pattern above: Yet another way is to introduce a @tech{splicing syntax class}, which is like an ordinary syntax class but for head patterns. -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mycond stx) (define-splicing-syntax-class maybe-fallthrough-option @@ -84,3 +86,5 @@ syntax class's variants. (This is possible to do in the inline pattern version too, using @racket[~and] and @racket[~parse], just less convenient.) Splicing syntax classes also closely parallel the style of grammars in macro documentation. + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/ex-many-kws.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/ex-many-kws.scrbl index 601f42ccd0..3bab7f7d91 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/ex-many-kws.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/ex-many-kws.scrbl @@ -6,6 +6,8 @@ "parse-common.rkt" (for-label racket/class)) +@(define the-eval (make-sp-eval)) + @title{More Keyword Arguments} This section shows how to express the syntax of @racket[struct]'s @@ -15,7 +17,7 @@ The part of @racket[struct]'s syntax that is difficult to specify is the sequence of struct options. Let's get the easy part out of the way first. -@myinteraction[ +@interaction[#:eval the-eval (define-splicing-syntax-class maybe-super (pattern (~seq super:id)) (pattern (~seq))) @@ -135,3 +137,5 @@ both @racket[#:guard] and @racket[#:property]. Repetition constraints cannot express arbitrary incompatibility relations. The best way to handle such constraints is with a side condition using @racket[#:fail-when]. + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/ex-mods-stxclasses.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/ex-mods-stxclasses.scrbl index 5863e8941f..9895cf37d0 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/ex-mods-stxclasses.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/ex-mods-stxclasses.scrbl @@ -6,6 +6,8 @@ "parse-common.rkt" (for-label racket/class)) +@(define the-eval (make-sp-eval)) + @title{Phases and Reusable Syntax Classes} As demonstrated in the @secref{stxparse-intro}, the simplest place to @@ -17,7 +19,7 @@ classes requires some awareness of the Racket @tech[#:doc '(lib syntax class defined immediately within a module cannot be used by macros in the same module; it is defined at the wrong phase. -@myinteraction[ +@interaction[#:eval the-eval (module phase-mismatch-mod racket (require syntax/parse (for-syntax syntax/parse)) (define-syntax-class foo @@ -37,7 +39,7 @@ phase level incompatibility.) The phase level mismatch is easily remedied by putting the syntax class definition within a @racket[begin-for-syntax] block: -@myinteraction[ +@interaction[#:eval the-eval (module phase-ok-mod racket (require (for-syntax syntax/parse)) (begin-for-syntax @@ -55,7 +57,7 @@ An alternative to @racket[begin-for-syntax] is to define the syntax class in a separate module and require that module @racket[for-syntax]. -@myinteraction[ +@interaction[#:eval the-eval (module stxclass-mod racket (require syntax/parse) (define-syntax-class foo @@ -77,7 +79,7 @@ expressions via syntax templates, then the module containing the syntax class must generally require @racket[for-template] the bindings referred to in the patterns and templates. -@myinteraction[ +@interaction[#:eval the-eval (module arith-keywords-mod racket (define-syntax plus (syntax-rules ())) (define-syntax times (syntax-rules ())) @@ -124,3 +126,5 @@ implicit syntax @racket[#%app]) must be bound at ``absolute'' phase level 0. Since the module @racket['arith-stxclass-mod] is required with a phase level offset of 1 (that is, @racket[for-syntax]), it must compensate with a phase level offset of -1, or @racket[for-template]. + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/experimental.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/experimental.scrbl index a05b647f8b..eadcb0ad94 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/experimental.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/experimental.scrbl @@ -5,6 +5,8 @@ scribble/eval "parse-common.rkt") +@(define the-eval (make-sp-eval)) + @title{Experimental} The following facilities are experimental. @@ -118,7 +120,7 @@ must be specified explicitly. Like @racket[~reflect] but for reified splicing syntax classes. } -@myexamples[ +@examples[#:eval the-eval (define-syntax-class (nat> x) #:description (format "natural number greater than ~s" x) #:attributes (diff) @@ -216,7 +218,7 @@ Includes the alternatives of @racket[eh-alternative-set-id], prefixing their attributes with @racket[name]. } -@myexamples[ +@examples[#:eval the-eval (define-eh-alternative-set options (pattern (~once (~seq #:a a:expr) #:name "#:a option")) (pattern (~seq #:b b:expr))) @@ -443,3 +445,5 @@ If @racket[join] were defined as a macro, it would not be usable in the context above; instead, @racket[let-values] would report an invalid binding list. } + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/intro.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/intro.scrbl index 6c57b9f4ed..28df9d80b1 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/intro.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/intro.scrbl @@ -6,6 +6,8 @@ "parse-common.rkt" (for-label (only-in syntax/parse ...+))) +@(define the-eval (make-sp-eval #f)) + @(define-syntax-rule (defdummy id) (defidentifier (quote-syntax id) #:form? #t #:index? #f #:show-libs? #f)) @@ -36,7 +38,7 @@ the second case later in the introduction. The macro can be implemented very simply using @racket[define-syntax-rule]: -@myinteraction[ +@interaction[#:eval the-eval (define-syntax-rule (mylet ([var rhs] ...) body ...) ((lambda (var ...) body ...) rhs ...)) ] @@ -47,7 +49,7 @@ uninformative error message; in others, it blithely accepts illegal syntax and passes it along to @racket[lambda], with strange consequences: -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a 1] [b 2]) (+ a b)) (mylet (b 2) (sub1 b)) (mylet ([1 a]) (add1 a)) @@ -70,13 +72,15 @@ We can improve the error behavior of the macro by using "scribblings/reference/reference.scrbl")]{transformer environment}, since we will use it to implement a macro transformer. -@myinteraction[(require (for-syntax syntax/parse))] +@interaction[#:eval the-eval +(require (for-syntax syntax/parse)) +] The following is the syntax specification above transliterated into a @racket[syntax-parse] macro definition. It behaves no better than the version using @racket[define-syntax-rule] above. -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mylet stx) (syntax-parse stx [(_ ([var-id rhs-expr] ...) body ...+) @@ -98,7 +102,7 @@ pattern variable name, a colon character, and the syntax class name.@margin-note*{For an alternative to the ``colon'' syntax, see the @racket[~var] pattern form.} -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mylet stx) (syntax-parse stx [(_ ((var:id rhs:expr) ...) body ...+) @@ -108,24 +112,24 @@ Note that the syntax class annotations do not appear in the template (i.e., @racket[var], not @racket[var:id]). The syntax class annotations are checked when we use the macro. -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a 1] [b 2]) (+ a b)) (mylet (["a" 1]) (add1 a)) ] The @racket[expr] syntax class does not actually check that the term it matches is a valid expression---that would require calling that macro expander. Instead, @racket[expr] just means not a keyword. -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a #:whoops]) 1) ] Also, @racket[syntax-parse] knows how to report a few kinds of errors without any help: -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a 1 2]) (* a a)) ] There are other kinds of errors, however, that this macro does not handle gracefully: -@myinteraction[ +@interaction[#:eval the-eval (mylet (a 1) (+ a 2)) ] It's too much to ask for the macro to respond, ``This expression is @@ -140,7 +144,7 @@ syntactic categories. One way of doing that is by defining new syntax classes:@margin-note*{Another way is the @racket[~describe] pattern form.} -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mylet stx) (define-syntax-class binding @@ -158,11 +162,11 @@ Note that we write @racket[b.var] and @racket[b.rhs] now. They are the syntax class @racket[binding]. Now the error messages can talk about ``binding pairs.'' -@myinteraction[ +@interaction[#:eval the-eval (mylet (a 1) (+ a 2)) ] Errors are still reported in more specific terms when possible: -@myinteraction[ +@interaction[#:eval the-eval (mylet (["a" 1]) (+ a 2)) ] @@ -170,13 +174,13 @@ There is one other constraint on the legal syntax of @racket[mylet]. The variables bound by the different binding pairs must be distinct. Otherwise the macro creates an illegal @racket[lambda] form: -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a 1] [a 2]) (+ a a)) ] Constraints such as the distinctness requirement are expressed as side conditions, thus: -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mylet stx) (define-syntax-class binding @@ -190,7 +194,7 @@ conditions, thus: "duplicate variable name" #'((lambda (b.var ...) body ...) b.rhs ...)])) ] -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a 1] [a 2]) (+ a a)) ] The @racket[#:fail-when] keyword is followed by two expressions: the @@ -202,7 +206,7 @@ pinpoint the cause of the failure. Syntax classes can have side conditions, too. Here is the macro rewritten to include another syntax class representing a ``sequence of distinct binding pairs.'' -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mylet stx) (define-syntax-class binding @@ -238,7 +242,7 @@ offered by Racket's @racket[let]. We must add the ``named-@racket[let]'' form. That turns out to be as simple as adding a new clause: -@myinteraction[ +@interaction[#:eval the-eval (define-syntax (mylet stx) (define-syntax-class binding @@ -267,7 +271,7 @@ lines. But does adding this new case affect @racket[syntax-parse]'s ability to pinpoint and report errors? -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a 1] [b 2]) (+ a b)) (mylet (["a" 1]) (add1 a)) (mylet ([a #:whoops]) 1) @@ -278,7 +282,7 @@ to pinpoint and report errors? The error reporting for the original syntax seems intact. We should verify that the named-@racket[let] syntax is working, that @racket[syntax-parse] is not simply ignoring that clause. -@myinteraction[ +@interaction[#:eval the-eval (mylet loop ([a 1] [b 2]) (+ a b)) (mylet loop (["a" 1]) (add1 a)) (mylet loop ([a #:whoops]) 1) @@ -300,7 +304,7 @@ potential errors (including ones like @racket[loop] not matching each error. Only the error with the most progress is reported. For example, in this bad use of the macro, -@myinteraction[ +@interaction[#:eval the-eval (mylet loop (["a" 1]) (add1 a)) ] there are two potential errors: expected @racket[distinct-bindings] at @@ -309,7 +313,7 @@ second error occurs further in the term than the first, so it is reported. For another example, consider this term: -@myinteraction[ +@interaction[#:eval the-eval (mylet (["a" 1]) (add1 a)) ] Again, there are two potential errors: expected @racket[identifier] at @@ -319,7 +323,7 @@ if you prefer), but the second error occurs deeper in the term. Progress is based on a left-to-right traversal of the syntax. A final example: consider the following: -@myinteraction[ +@interaction[#:eval the-eval (mylet ([a 1] [a 2]) (+ a a)) ] There are two errors again: duplicate variable name at @racket[([a 1] @@ -339,7 +343,7 @@ the term. It is, however, possible for multiple potential errors to occur with the same progress. Here's one example: -@myinteraction[ +@interaction[#:eval the-eval (mylet "not-even-close") ] In this case @racket[syntax-parse] reports both errors. @@ -347,7 +351,7 @@ In this case @racket[syntax-parse] reports both errors. Even with all of the annotations we have added to our macro, there are still some misuses that defy @racket[syntax-parse]'s error reporting capabilities, such as this example: -@myinteraction[ +@interaction[#:eval the-eval (mylet) ] The philosophy behind @racket[syntax-parse] is that in these @@ -363,3 +367,5 @@ conditions, and progress-ordered error reporting. But @secref{stxparse-examples} section for samples of other features in working code, or skip to the subsequent sections for the complete reference documentation. + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/litconv.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/litconv.scrbl index 7a8b047364..484df5cf08 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/litconv.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/litconv.scrbl @@ -5,6 +5,8 @@ scribble/eval "parse-common.rkt") +@(define the-eval (make-sp-eval)) + @title{Literal Sets and Conventions} Sometimes the same literals are recognized in a number of different @@ -38,7 +40,7 @@ identifiers the literal matches. If the @racket[#:literal-sets] option is present, the contents of the given @racket[imported-litset-id]s are included. -@myexamples[ +@examples[#:eval the-eval (define-literal-set def-litset (define-values define-syntaxes)) (syntax-parse #'(define-syntaxes (x) 12) @@ -56,7 +58,7 @@ given, then @racket[phase-level] is @racket[0]. For example: -@myexamples[ +@interaction[#:eval the-eval (module common racket/base (define x 'something) (provide x)) @@ -74,7 +76,7 @@ module @racketmodname['common]. The following module defines an equivalent literal set, but imports the @racket['common] module for-template instead: -@myexamples[ +@interaction[#:eval the-eval (module lits racket/base (require syntax/parse (for-template 'common)) (define-literal-set common-lits #:for-template (x)) @@ -85,7 +87,7 @@ When a literal set is @emph{used} with the @racket[#:phase phase-expr] option, the literals' fixed bindings are compared against the binding of the input literal at the specified phase. Continuing the example: -@myexamples[ +@interaction[#:eval the-eval (require syntax/parse 'lits (for-syntax 'common)) (syntax-parse #'x #:literal-sets ([common-lits #:phase 1]) [x 'yes] @@ -106,7 +108,7 @@ phase @racket[_phase] at which to examine the binding of @racket[_id]; the @racket[_phase] argument defaults to @racket[(syntax-local-phase-level)]. -@myexamples[ +@examples[#:eval the-eval (define kernel? (literal-set->predicate kernel-literals)) (kernel? #'lambda) (kernel? #'#%plain-lambda) @@ -130,7 +132,7 @@ that matches determines the syntax class for the pattern. If no @racket[name-pattern] matches, then the pattern variable has no syntax class. -@myexamples[ +@examples[#:eval the-eval (define-conventions xyz-as-ids [x id] [y id] [z id]) (syntax-parse #'(a b c 1 2 3) @@ -149,7 +151,7 @@ Local conventions, introduced with the @racket[#:local-conventions] keyword argument of @racket[syntax-parse] and syntax class definitions, may refer to local bindings: -@myexamples[ +@examples[#:eval the-eval (define-syntax-class (nat> bound) (pattern n:nat #:fail-unless (> (syntax-e #'n) bound) @@ -168,3 +170,5 @@ definitions, may refer to local bindings: ] } + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt b/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt index 6febe969da..4735433336 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt +++ b/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt @@ -1,16 +1,14 @@ #lang racket/base (require scribble/manual scribble/eval + racket/string racket/sandbox) - (provide ellipses - the-eval - myexamples - myinteraction) + make-sp-eval) (define ellipses (racket ...)) -(define (fixup exn) +(define (fixup/short exn) (let ([src (ormap values (exn:fail:syntax-exprs exn))]) (if src (make-exn:fail:syntax @@ -21,37 +19,46 @@ (exn-continuation-marks exn) (exn:fail:syntax-exprs exn)) exn))) -(define the-eval - (call-with-trusted-sandbox-configuration - (lambda () - (parameterize ([sandbox-output 'string] - [sandbox-error-output 'string] - [sandbox-propagate-breaks #f] - [sandbox-eval-handlers - (list #f - (lambda (thunk) - (with-handlers ([exn:fail:syntax? - (lambda (e) (raise (fixup e)))]) - (thunk))))]) - (make-evaluator 'racket/base - #:requires (let ([mods '(racket/promise - syntax/parse - syntax/parse/debug - syntax/parse/experimental/splicing - syntax/parse/experimental/contract - syntax/parse/experimental/reflect - syntax/parse/experimental/specialize - syntax/parse/experimental/template - syntax/parse/experimental/eh)]) - `((for-syntax racket/base ,@mods) - ,@mods))))))) -(the-eval '(error-print-source-location #f)) -(define-syntax-rule (myexamples e ...) - (examples #:eval the-eval e ...)) +(define (fixup/long exn) + (let ([src (ormap values (exn:fail:syntax-exprs exn))]) + (if src + (make-exn:fail:syntax + (string-trim (exn-message exn) + #rx"[^ ]*[ ]" + #:left? #t #:right? #f) + (exn-continuation-marks exn) + (exn:fail:syntax-exprs exn)) + exn))) -(define-syntax-rule (myinteraction e ...) - (interaction #:eval the-eval e ...)) +(define (make-sp-eval [short? #f]) + (define fixup (if short? fixup/short fixup/long)) + (define the-eval + (call-with-trusted-sandbox-configuration + (lambda () + (parameterize ([sandbox-output 'string] + [sandbox-error-output 'string] + [sandbox-propagate-breaks #f] + [sandbox-eval-handlers + (list #f + (lambda (thunk) + (with-handlers ([exn:fail:syntax? + (lambda (e) (raise (fixup e)))]) + (thunk))))]) + (make-evaluator 'racket/base + #:requires (let ([mods '(racket/promise + syntax/parse + syntax/parse/debug + syntax/parse/experimental/splicing + syntax/parse/experimental/contract + syntax/parse/experimental/reflect + syntax/parse/experimental/specialize + syntax/parse/experimental/template + syntax/parse/experimental/eh)]) + `((for-syntax racket/base ,@mods) + ,@mods))))))) + (when short? (the-eval '(error-print-source-location #f))) + the-eval) ;; ---- diff --git a/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl index 5f3d7d22a8..133df9639d 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/parsing.scrbl @@ -6,6 +6,8 @@ "parse-common.rkt" (for-label racket/syntax)) +@(define the-eval (make-sp-eval)) + @title{Parsing Syntax} This section describes @racket[syntax-parse], the @@ -79,15 +81,16 @@ is inferred as with @racket[raise-syntax-error]. The @racket[current-syntax-context] parameter is also set to the syntax object @racket[_context-stx]. -@(myexamples - (syntax-parse #'(a b 3) - [(x:id ...) 'ok]) - (syntax-parse #'(a b 3) - #:context #'(lambda (a b 3) (+ a b)) - [(x:id ...) 'ok]) - (syntax-parse #'(a b 3) - #:context 'check-id-list - [(x:id ...) 'ok])) +@examples[#:eval the-eval +(syntax-parse #'(a b 3) + [(x:id ...) 'ok]) +(syntax-parse #'(a b 3) + #:context #'(lambda (a b 3) (+ a b)) + [(x:id ...) 'ok]) +(syntax-parse #'(a b 3) + #:context 'check-id-list + [(x:id ...) 'ok]) +] } @specsubform[(code:line #:literals (literal ...)) @@ -172,7 +175,7 @@ bindings. See the section on @tech{conventions} for examples. Suppresses the ``colon notation'' for annotated pattern variables. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(a b c) [(x:y ...) 'ok]) (syntax-parse #'(a b c) #:disable-colon-notation @@ -195,7 +198,7 @@ syntax object result of @racket[stx-expr] against @racket[syntax-pattern] and creates pattern variable definitions for the attributes of @racket[syntax-pattern]. -@myexamples[ +@examples[#:eval the-eval (define/syntax-parse ((~seq kw:keyword arg:expr) ...) #'(#:a 1 #:b 2 #:c 3)) #'(kw ...) @@ -204,3 +207,5 @@ the attributes of @racket[syntax-pattern]. Compare with @racket[define/with-syntax], a similar definition form that uses the simpler @racket[syntax-case] patterns. } + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl index 8d6baee336..d1fd1b5904 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl @@ -5,6 +5,8 @@ scribble/eval "parse-common.rkt") +@(define the-eval (make-sp-eval)) + @(define-syntax-rule (define-dotsplus-names dotsplus def-dotsplus) (begin (require (for-label (only-in syntax/parse ...+))) (define dotsplus (racket ...+)) @@ -200,7 +202,7 @@ An identifier can be either a @tech{pattern variable}, an literals list, it is a @tech{literal} pattern that behaves like @racket[(~literal id)]. - @myexamples[ + @examples[#:eval the-eval (syntax-parse #'(define x 12) #:literals (define) [(define var:id body:expr) 'ok]) @@ -221,7 +223,7 @@ An identifier can be either a @tech{pattern variable}, an @tech{annotated pattern variable}, and the pattern is equivalent to @racket[(~var _pvar-id _syntax-class-id)]. - @myexamples[ + @examples[#:eval the-eval (syntax-parse #'a [var:id (syntax-e #'var)]) (syntax-parse #'12 @@ -246,7 +248,7 @@ An identifier can be either a @tech{pattern variable}, an where @racket[_literal-id] is in the literals list, then it is equivalent to @racket[(~and (~var _pvar-id) literal-id)]. - @myexamples[ + @examples[#:eval the-eval (require (only-in racket/base [define def])) (syntax-parse #'(def x 7) #:literals (define) @@ -299,7 +301,7 @@ If @svar[pvar-id] is @racket[_], no attributes are bound. If If @racket[role-expr] is given and evaluates to a string, it is combined with the syntax class's description in error messages. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'a [(~var var id) (syntax-e #'var)]) (syntax-parse #'12 @@ -327,7 +329,7 @@ combined with the syntax class's description in error messages. A @deftech{literal} identifier pattern. Matches any identifier @racket[free-identifier=?] to @racket[literal-id]. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(define x 12) [((~literal define) var:id body:expr) 'ok]) (syntax-parse #'(lambda x 12) @@ -344,7 +346,7 @@ The identifiers are compared at the phase given by Numbers, strings, booleans, keywords, and the empty list match as literals. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(a #:foo bar) [(x #:foo y) (syntax->datum #'y)]) (syntax-parse #'(a foo bar) @@ -358,7 +360,7 @@ Matches syntax whose S-expression contents (obtained by @racket[syntax->datum]) is @racket[equal?] to the given @racket[datum]. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(a #:foo bar) [(x (~datum #:foo) y) (syntax->datum #'y)]) (syntax-parse #'(a foo bar) @@ -369,7 +371,7 @@ The @racket[~datum] form is useful for recognizing identifiers symbolically, in contrast to the @racket[~literal] form, which recognizes them by binding. -@myexamples[ +@examples[#:eval the-eval (syntax-parse (let ([define 'something-else]) #'(define x y)) [((~datum define) var:id e:expr) 'yes] [_ 'no]) @@ -435,7 +437,7 @@ That is, the following patterns are equivalent: @item[@racket[((~between H 1 +inf.0) ... . S)]] ] -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(1 2 3) [(n:nat ...+) 'ok]) (syntax-parse #'() @@ -461,7 +463,7 @@ term (including its lexical context, source location, etc) while also examining its structure. Syntax classes are useful for the same purpose, but @racket[~and] can be lighter weight. -@myexamples[ +@examples[#:eval the-eval (define-syntax (import stx) (raise-syntax-error #f "illegal use of import" stx)) (eval:alts @@ -490,7 +492,7 @@ of @racket[#f]. The same attribute may be bound by multiple subpatterns, and if it is bound by all of the subpatterns, it is sure to have a value if the whole pattern matches. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'a [(~or x:id y:nat) (values (attribute x) (attribute y))]) (syntax-parse #'(a 1) @@ -506,7 +508,7 @@ Matches any term that does not match the subpattern. None of the subpattern's attributes are bound outside of the @racket[~not]-pattern. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(x y z => u v) #:literals (=>) [((~and before (~not =>)) ... => after ...) @@ -520,7 +522,7 @@ Matches a term that is a vector whose elements, when considered as a list, match the @tech{@Spattern} corresponding to @racket[(pattern-part ...)]. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'#(1 2 3) [#(x y z) (syntax->datum #'z)]) (syntax-parse #'#(1 2 3) @@ -536,7 +538,7 @@ Matches a term that is a prefab struct whose key is exactly the given key and whose sequence of fields, when considered as a list, match the @tech{@Spattern} corresponding to @racket[(pattern-part ...)]. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'#s(point 1 2 3) [#s(point x y z) 'ok]) (syntax-parse #'#s(point 1 2 3) @@ -551,7 +553,7 @@ key and whose sequence of fields, when considered as a list, match the Matches a term that is a box whose contents matches the inner @tech{@Spattern}. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'#&5 [#&n:nat 'ok]) ] @@ -564,7 +566,7 @@ is useful in positions where improper (``dotted'') lists are not allowed by the reader, such as vector and structure patterns (see above). -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(1 2 3) [(x ~rest y) (syntax->datum #'y)]) (syntax-parse #'#(1 2 3) @@ -594,7 +596,7 @@ terms of the description given. If @racket[role-expr] is given and produces a string, its value is combined with the description in error messages. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(m 1) [(_ (~describe "id pair" (x:id y:id))) 'ok]) (syntax-parse #'(m (a 2)) @@ -681,7 +683,7 @@ matches a head pattern. Matches a sequence of terms whose elements, if put in a list, would match @racket[L-pattern]. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(1 2 3 4) [((~seq 1 2 3) 4) 'ok]) ] @@ -695,7 +697,7 @@ examples of @racket[~seq]. Like the @Spattern version, @ref[~and s], but matches a sequence of terms instead. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(#:a 1 #:b 2 3 4 5) [((~and (~seq (~seq k:keyword e:expr) ...) (~seq keyword-stuff ...)) @@ -708,7 +710,7 @@ subpatterns be @tech{proper @Hpatterns} (not @tech{@Spatterns}). This is to prevent typos like the following, a variant of the previous example with the second @racket[~seq] omitted: -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(#:a 1 #:b 2 3 4 5) [((~and (~seq (~seq k:keyword e:expr) ...) (keyword-stuff ...)) @@ -728,7 +730,7 @@ example with the second @racket[~seq] omitted: Like the @Spattern version, @ref[~or s], but matches a sequence of terms instead. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(m #:foo 2 a b c) [(_ (~or (~seq #:foo x) (~seq)) y:id ...) (attribute x)]) @@ -752,7 +754,7 @@ terms. If the @racket[#:defaults] option is given, the subsequent attribute bindings are used if the subpattern does not match. The default attributes must be a subset of the subpattern's attributes. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(m #:foo 2 a b c) [(_ (~optional (~seq #:foo x) #:defaults ([x #'#f])) y:id ...) (attribute x)]) @@ -812,7 +814,7 @@ matching position, so the pattern consumes no input. Used to look ahead in a sequence. None of the subpattern's attributes are bound outside of the @racket[~peek-not]-pattern. -@myexamples[ +@examples[#:eval the-eval (define-splicing-syntax-class final (code:comment "final term") (pattern (~seq x (~peek-not _)))) @@ -841,7 +843,7 @@ repetition. They are useful for matching, for example, keyword arguments where the keywords may come in any order. Multiple alternatives are grouped together via @ref[~or eh]. -@myexamples[ +@examples[#:eval the-eval (define parser1 (syntax-parser [((~or (~once (~seq #:a x) #:name "#:a keyword") @@ -1041,7 +1043,7 @@ There is currently no way to bind attributes using a @racket[~do] pattern. It is an error to shadow an attribute binding with a definition in a @racket[~do] block. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(1 2 3) [(a b (~do (printf "a was ~s\n" #'a)) c:id) 'ok]) ] @@ -1065,7 +1067,7 @@ forms by rewriting them into existing pattern forms. Returns a @tech{pattern expander} that uses @racket[proc] to transform the pattern. -@myexamples[ +@examples[#:eval the-eval (define-syntax ~maybe (pattern-expander (syntax-rules () @@ -1100,3 +1102,5 @@ Returns @racket[#t] if @racket[v] is a @tech{pattern expander}, Like @racket[syntax-local-introduce], but for @tech{pattern expanders}. } + +@(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl index 4d932754a3..4681ba3286 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl @@ -5,6 +5,8 @@ scribble/eval "parse-common.rkt") +@(define the-eval (make-sp-eval)) + @title[#:tag "stxparse-specifying"]{Specifying Syntax with Syntax Classes} @declare-exporting[syntax/parse] @@ -204,7 +206,7 @@ If a @racket[#:with] directive appears between the main pattern (e.g., in a @racket[#:declare], then only pattern variables from the @racket[#:with] pattern may be declared. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'P [x #:declare x id @@ -322,7 +324,7 @@ subterm. A non-syntax-valued attribute should be bound using the and @racket[~parse] will convert the right-hand side to a (possibly 3D) syntax object. -@myexamples[ +@examples[#:eval the-eval (define-syntax-class table (pattern ((key value) ...) #:attr hashtable @@ -347,7 +349,7 @@ used in a syntax template. Syntax-valued attributes can be used in syntax templates: -@myinteraction[ +@interaction[#:eval the-eval (syntax-parse #'((a 3) (b 2) (c 1)) [t:table #'(t.key ...)]) @@ -357,7 +359,7 @@ Syntax-valued attributes can be used in syntax templates: But non-syntax-valued attributes cannot: -@myinteraction[ +@interaction[#:eval the-eval (syntax-parse #'((a 3) (b 2) (c 1)) [t:table #'t.hashtable]) @@ -366,7 +368,7 @@ But non-syntax-valued attributes cannot: Use the @racket[attribute] form to get the value of an attribute (syntax-valued or not). -@myinteraction[ +@interaction[#:eval the-eval (syntax-parse #'((a 1) (b 2) (c 3)) [t:table (attribute t.hashtable)]) @@ -409,7 +411,7 @@ it is syntax-valued. In particular, @racket[~or] and expected levels of list nesting, and @racket[#:attr] and @racket[~bind] can be used to bind attributes to arbitrary values. -@myexamples[ +@examples[#:eval the-eval (syntax-parse #'(a b 3) [(~or (x:id ...) _) (attribute x)]) @@ -421,3 +423,5 @@ Returns the value associated with the @tech{attribute} named @racket[attr-id]. If @racket[attr-id] is not bound as an attribute, an error is raised. } + +@(close-eval the-eval) From 2923a3adcfed4a10fc756ee8b8e208d266ae191b Mon Sep 17 00:00:00 2001 From: Alex Knauth Date: Fri, 11 Sep 2015 17:03:55 -0400 Subject: [PATCH 202/381] syntax/parse: fix disappeared-use property in attribute macro This fixes the DrRacket check syntax arrows in uses of `attribute` like this: ```racket #lang racket/base (require syntax/parse) (syntax-parse #'a [a (attribute a)]) ``` --- racket/collects/syntax/parse/private/residual.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/syntax/parse/private/residual.rkt b/racket/collects/syntax/parse/private/residual.rkt index 1f71d3097e..2935f4d474 100644 --- a/racket/collects/syntax/parse/private/residual.rkt +++ b/racket/collects/syntax/parse/private/residual.rkt @@ -99,7 +99,7 @@ (raise-syntax-error #f "not bound as an attribute" stx #'name)) (syntax-property (attribute-mapping-var attr) 'disappeared-use - #'name))))])) + (list (syntax-local-introduce #'name))))))])) ;; (attribute-binding id) ;; mostly for debugging/testing From 29223aaed7fef92fda52f8c6da9a55d8750dbf5e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 13:53:41 -0600 Subject: [PATCH 203/381] raco pkg: wrap network access with retries Retry communication up to five times when `exn:fail:network` is raised. Not all `exn:fail:network` exceptions are transient. For example, attempting to connect to a bad server name will produce an error more slowly than before, since the bad connection will be tried five times. Still, retrying on `exn:fail:network` seems like a good heuristic. --- racket/collects/pkg/private/catalog.rkt | 24 ++++----- racket/collects/pkg/private/download.rkt | 68 +++++++++++------------- racket/collects/pkg/private/network.rkt | 51 ++++++++++++++++++ racket/collects/pkg/private/stage.rkt | 35 ++++++------ 4 files changed, 110 insertions(+), 68 deletions(-) create mode 100644 racket/collects/pkg/private/network.rkt diff --git a/racket/collects/pkg/private/catalog.rkt b/racket/collects/pkg/private/catalog.rkt index d95228212c..2b0ea8d838 100644 --- a/racket/collects/pkg/private/catalog.rkt +++ b/racket/collects/pkg/private/catalog.rkt @@ -8,7 +8,8 @@ "params.rkt" "config.rkt" "print.rkt" - "prefetch.rkt") + "prefetch.rkt" + "network.rkt") (provide select-info-version source->relative-source @@ -236,19 +237,14 @@ ;; uses a custodian to avoid leaks: (define (call-with-url url handler) - (define c (make-custodian)) - (dynamic-wind - void - (lambda () - (define-values (p hs) - (parameterize ([current-custodian c]) - (get-pure-port/headers url #:redirections 25 #:status? #t))) - (begin0 - (and (string=? "200" (substring hs 9 12)) - (handler p)) - (close-input-port p))) - (lambda () - (custodian-shutdown-all c)))) + (call-with-network-retries + (lambda () + (define-values (p hs) + (get-pure-port/headers url #:redirections 25 #:status? #t)) + (begin0 + (and (string=? "200" (substring hs 9 12)) + (handler p)) + (close-input-port p))))) (define (db-pkg-info pkg details?) (if details? diff --git a/racket/collects/pkg/private/download.rkt b/racket/collects/pkg/private/download.rkt index 93325312c2..8199c822ff 100644 --- a/racket/collects/pkg/private/download.rkt +++ b/racket/collects/pkg/private/download.rkt @@ -10,27 +10,14 @@ net/git-checkout "path.rkt" "print.rkt" - "config.rkt") + "config.rkt" + "network.rkt") -(provide call/input-url+200 - download-file! +(provide download-file! download-repo! url-path/no-slash clean-cache) -(define (call/input-url+200 u fun - #:headers [headers '()] - #:failure [fail-k (lambda (s) #f)]) - #;(printf "\t\tReading ~a\n" (url->string u)) - (define-values (ip hs) (get-pure-port/headers u headers - #:redirections 25 - #:status? #t)) - (if (string=? "200" (substring hs 9 12)) - (begin0 - (fun ip) - (close-input-port ip)) - (fail-k hs))) - (define (url-path/no-slash url) (define p (url-path url)) (define rp (reverse p)) @@ -72,20 +59,23 @@ (define (download!) (when download-printf (download-printf "Downloading ~a\n" (url->string url))) - (call-with-output-file* - file - #:exists 'truncate/replace - (λ (op) - (call/input-url+200 - url - (λ (ip) (copy-port ip op)) - #:failure - (lambda (reply-s) - (pkg-error (~a "error downloading package\n" - " URL: ~a\n" - " server response: ~a") - (url->string url) - (read-line (open-input-string reply-s)))))))) + (call-with-network-retries + (lambda () + (call-with-output-file* + file + #:exists 'truncate/replace + (λ (op) + (call/input-url+200 + url + (λ (ip) (copy-port ip op)) + #:auto-retry? #f + #:failure + (lambda (reply-s) + (pkg-error (~a "error downloading package\n" + " URL: ~a\n" + " server response: ~a") + (url->string url) + (read-line (open-input-string reply-s)))))))))) (do-cache-file file url checksum use-cache? download-printf download!))) (define (clean-cache pkg-url checksum) @@ -109,14 +99,16 @@ (define (download!) (when download-printf (download-printf "Downloading repository ~a\n" (url->string url))) - (git-checkout host #:port port repo - #:dest-dir dest-dir - #:ref checksum - #:status-printf (lambda (fmt . args) - (define (strip-ending-newline s) - (regexp-replace #rx"\n$" s "")) - (log-pkg-debug (strip-ending-newline (apply format fmt args)))) - #:transport transport) + (call-with-network-retries + (lambda () + (git-checkout host #:port port repo + #:dest-dir dest-dir + #:ref checksum + #:status-printf (lambda (fmt . args) + (define (strip-ending-newline s) + (regexp-replace #rx"\n$" s "")) + (log-pkg-debug (strip-ending-newline (apply format fmt args)))) + #:transport transport))) (set! unpacked? #t) ;; package directory as ".tgz" so it can be cached: (parameterize ([current-directory dest-dir]) diff --git a/racket/collects/pkg/private/network.rkt b/racket/collects/pkg/private/network.rkt new file mode 100644 index 0000000000..2415f5cbe1 --- /dev/null +++ b/racket/collects/pkg/private/network.rkt @@ -0,0 +1,51 @@ +#lang racket/base +(require net/url + "print.rkt") + +(provide call-with-network-retries + call/input-url+200) + +(define NETWORK-RETRY-COUNT 5) +(define NETWORK-INITIAL-PAUSE 0.1) + +;; Retry `thunk` on any `exn:fail:network` exception. A fresh +;; custodian is in place during the call to `thunk`, so resources +;; are reliably cleaned up (and cannt be allocated and returned +;; by `thunk`, except by using a different custodian). +(define (call-with-network-retries thunk) + (let loop ([retries NETWORK-RETRY-COUNT] [pause-time NETWORK-INITIAL-PAUSE]) + (with-handlers ([exn:fail:network? (lambda (exn) + (cond + [(zero? retries) + (raise exn)] + [else + ;; Pause, then try again + (log-pkg-info "Network error; retrying after ~as" + pause-time) + (sleep pause-time) + (loop (sub1 retries) (* 2 pause-time))]))]) + (define c (make-custodian)) + (parameterize ([current-custodian c]) + (dynamic-wind + void + thunk + (lambda () + (custodian-shutdown-all c))))))) + +(define (call/input-url+200 u fun + #:auto-retry? [auto-retry? #t] + #:headers [headers '()] + #:failure [fail-k (lambda (s) #f)]) + ((if auto-retry? + call-with-network-retries + (lambda (f) (f))) + (lambda () + #;(printf "\t\tReading ~a\n" (url->string u)) + (define-values (ip hs) (get-pure-port/headers u headers + #:redirections 25 + #:status? #t)) + (if (string=? "200" (substring hs 9 12)) + (begin0 + (fun ip) + (close-input-port ip)) + (fail-k hs))))) diff --git a/racket/collects/pkg/private/stage.rkt b/racket/collects/pkg/private/stage.rkt index d8c86a731a..8f3fd17975 100644 --- a/racket/collects/pkg/private/stage.rkt +++ b/racket/collects/pkg/private/stage.rkt @@ -29,7 +29,8 @@ "repo-path.rkt" "orig-pkg.rkt" "git.rkt" - "prefetch.rkt") + "prefetch.rkt" + "network.rkt") (provide (struct-out install-info) remote-package-checksum @@ -732,21 +733,23 @@ (define-values (transport host port repo branch path) (split-git-or-hub-url pkg-url #:type type)) (download-printf "Querying Git references for ~a at ~a\n" pkg-name pkg-url-str) - ;; Supplying `#:dest-dir #f` means that we just resolve `branch` - ;; to an ID: - (git-checkout host #:port port repo - #:dest-dir #f - #:ref branch - #:status-printf (lambda (fmt . args) - (define (strip-ending-newline s) - (regexp-replace #rx"\n$" s "")) - (log-pkg-debug (strip-ending-newline (apply format fmt args)))) - #:initial-error (lambda () - (pkg-error (~a "Git checkout initial protocol failed;\n" - " the given URL might not refer to a Git repository\n" - " given URL: ~a") - pkg-url-str)) - #:transport transport)] + (call-with-network-retries + (lambda () + ;; Supplying `#:dest-dir #f` means that we just resolve `branch` + ;; to an ID: + (git-checkout host #:port port repo + #:dest-dir #f + #:ref branch + #:status-printf (lambda (fmt . args) + (define (strip-ending-newline s) + (regexp-replace #rx"\n$" s "")) + (log-pkg-debug (strip-ending-newline (apply format fmt args)))) + #:initial-error (lambda () + (pkg-error (~a "Git checkout initial protocol failed;\n" + " the given URL might not refer to a Git repository\n" + " given URL: ~a") + pkg-url-str)) + #:transport transport)))] [(github) (match-define (list* user repo branch path) (split-github-url pkg-url)) From dcfb9cb972e543b76021b9674a794971e11f9d98 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 14:46:37 -0600 Subject: [PATCH 204/381] raco pkg: make `network-retries` configurable --- pkgs/racket-doc/pkg/scribblings/lib.scrbl | 12 ++++++++++ pkgs/racket-doc/pkg/scribblings/pkg.scrbl | 5 ++++- racket/collects/pkg/lib.rkt | 2 ++ racket/collects/pkg/private/config.rkt | 20 ++++++++++++----- racket/collects/pkg/private/network.rkt | 27 ++++++++++++----------- racket/collects/pkg/private/params.rkt | 2 ++ 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/pkgs/racket-doc/pkg/scribblings/lib.scrbl b/pkgs/racket-doc/pkg/scribblings/lib.scrbl index 13cf6f6444..b32916016b 100644 --- a/pkgs/racket-doc/pkg/scribblings/lib.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/lib.scrbl @@ -103,6 +103,18 @@ used. @history[#:added "6.1.1.6"]} +@deftogether[( +@defparam[current-pkg-network-retries max-retries (or/c #f real?)] +)]{ + +A parameter that determines the number of times to retry a network communication +that fails due to a connection error. If +a parameter's value is @racket[#f], then the user's configuration is +used. + +@history[#:added "6.2.900.17"]} + + @defproc[(pkg-directory [name string?] [#:cache cache (or/c #f (and/c hash? (not/c immutable?))) #f]) (or/c path-string? #f)]{ diff --git a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl index c580f061d3..a44ec11f21 100644 --- a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -940,9 +940,12 @@ for @nonterm{key}. updated that its implementation is kept in the trash folder. Package implementations are removed from a trash folder only when another package is potentially added to the trash folder or @command-ref{empty-trash} is used.} + @item{@exec{network-retries} --- The number of times to retry a network communication that + fails due to a connection error.} ] -@history[#:changed "6.1.1.6" @elem{Added @exec{trash-max-packages} and @exec{trash-max-seconds}.}]} +@history[#:changed "6.1.1.6" @elem{Added @exec{trash-max-packages} and @exec{trash-max-seconds}.} + #:changed "6.2.900.17" @elem{Added @exec{network-retries}.}]} @subcommand{@command/toc{catalog-show} @nonterm{option} ... @nonterm{package-name} ... diff --git a/racket/collects/pkg/lib.rkt b/racket/collects/pkg/lib.rkt index f5589d499b..a4a51c8795 100644 --- a/racket/collects/pkg/lib.rkt +++ b/racket/collects/pkg/lib.rkt @@ -67,6 +67,8 @@ (parameter/c (or/c #f real?))] [current-pkg-trash-max-seconds (parameter/c (or/c #f real?))] + [current-pkg-network-retries + (parameter/c (or/c #f real?))] [pkg-directory (->* (string?) (#:cache (or/c #f (and/c hash? (not/c immutable?)))) diff --git a/racket/collects/pkg/private/config.rkt b/racket/collects/pkg/private/config.rkt index fc1c024af8..73e0feb3ce 100644 --- a/racket/collects/pkg/private/config.rkt +++ b/racket/collects/pkg/private/config.rkt @@ -33,6 +33,10 @@ (or (current-pkg-trash-max-seconds) (read-pkg-cfg/def 'trash-max-seconds))) +(define (get-network-retries) + (or (current-pkg-network-retries) + (read-pkg-cfg/def 'network-retries))) + (define (read-pkg-cfg/def k) ;; Lock is held for the current scope, but if ;; the key is not found in the current scope, @@ -51,6 +55,7 @@ ['download-cache-max-bytes (* 64 1024 1024)] ['trash-max-packages 512] ['trash-max-seconds (* 60 60 24 2)] ; 2 days + ['network-retries 5] [_ #f])) (define c (read-pkg-file-hash (pkg-config-file))) (define v (hash-ref c k 'none)) @@ -122,7 +127,8 @@ "download-cache-dir" "doc-open-url" "trash-max-packages" - "trash-max-seconds"))) + "trash-max-seconds" + "network-retries"))) (pkg-error (~a "missing value for config key\n" " config key: ~a") key)] @@ -134,7 +140,8 @@ "download-cache-dir" "doc-open-url" "trash-max-packages" - "trash-max-seconds")) + "trash-max-seconds" + "network-retries")) val another-val more-vals) @@ -173,7 +180,8 @@ [(list (and key (or "download-cache-max-files" "download-cache-max-bytes" "trash-max-packages" - "trash-max-seconds")) + "trash-max-seconds" + "network-retries")) val) (unless (real? (string->number val)) (pkg-error (~a "invalid value for config key\n" @@ -207,7 +215,8 @@ "download-cache-max-files" "download-cache-max-bytes" "trash-max-packages" - "trash-max-seconds") + "trash-max-seconds" + "network-retries") (printf "~a~a\n" indent (read-pkg-cfg/def (string->symbol key)))] ["doc-open-url" (printf "~a~a\n" indent (or (read-pkg-cfg/def 'doc-open-url) ""))] @@ -229,7 +238,8 @@ "download-cache-max-files" "download-cache-max-bytes" "trash-max-packages" - "trash-max-seconds"))]) + "trash-max-seconds" + "network-retries"))]) (printf "~a:\n" key) (show (list key) " "))] [_ (show key+vals "")])])) diff --git a/racket/collects/pkg/private/network.rkt b/racket/collects/pkg/private/network.rkt index 2415f5cbe1..7ee8ae3f8f 100644 --- a/racket/collects/pkg/private/network.rkt +++ b/racket/collects/pkg/private/network.rkt @@ -1,11 +1,11 @@ #lang racket/base (require net/url - "print.rkt") + "print.rkt" + "config.rkt") (provide call-with-network-retries call/input-url+200) -(define NETWORK-RETRY-COUNT 5) (define NETWORK-INITIAL-PAUSE 0.1) ;; Retry `thunk` on any `exn:fail:network` exception. A fresh @@ -13,17 +13,18 @@ ;; are reliably cleaned up (and cannt be allocated and returned ;; by `thunk`, except by using a different custodian). (define (call-with-network-retries thunk) - (let loop ([retries NETWORK-RETRY-COUNT] [pause-time NETWORK-INITIAL-PAUSE]) - (with-handlers ([exn:fail:network? (lambda (exn) - (cond - [(zero? retries) - (raise exn)] - [else - ;; Pause, then try again - (log-pkg-info "Network error; retrying after ~as" - pause-time) - (sleep pause-time) - (loop (sub1 retries) (* 2 pause-time))]))]) + (define retry-count (get-network-retries)) + (let loop ([retries 0] [pause-time NETWORK-INITIAL-PAUSE]) + (with-handlers* ([exn:fail:network? (lambda (exn) + (cond + [(retries . >= . retry-count) + (raise exn)] + [else + ;; Pause, then try again + (log-pkg-info "Network error; retrying after ~as" + pause-time) + (sleep pause-time) + (loop (add1 retries) (* 2 pause-time))]))]) (define c (make-custodian)) (parameterize ([current-custodian c]) (dynamic-wind diff --git a/racket/collects/pkg/private/params.rkt b/racket/collects/pkg/private/params.rkt index 541979f441..e99d25bef2 100644 --- a/racket/collects/pkg/private/params.rkt +++ b/racket/collects/pkg/private/params.rkt @@ -32,3 +32,5 @@ (define current-pkg-trash-max-seconds (make-parameter #f)) +(define current-pkg-network-retries + (make-parameter #f)) From 696c9d972fc50a8badc6c7d0298eb9f5fcabc197 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 15:03:10 -0600 Subject: [PATCH 205/381] prohibit directory indicators in "git:....?path=" as a package source Closes #1027 --- pkgs/racket-test/tests/pkg/tests-name.rkt | 2 ++ racket/collects/pkg/name.rkt | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/pkgs/racket-test/tests/pkg/tests-name.rkt b/pkgs/racket-test/tests/pkg/tests-name.rkt index fbbe2930cb..9f5c50a395 100644 --- a/pkgs/racket-test/tests/pkg/tests-name.rkt +++ b/pkgs/racket-test/tests/pkg/tests-name.rkt @@ -115,6 +115,7 @@ (check-equal-values? (parse "git://github.com/../fish" #f #rx"indicator") (values #f 'github #f)) (check-equal-values? (parse "git://github.com/racket/fish" 'clone) (values "fish" 'clone #t)) (check-equal-values? (parse "racket/fish" 'github) (values "fish" 'github #t)) + (check-equal-values? (parse "git://github.com/racket/fish/?path=../bill" #f #rx"indicator") (values #f 'github #f)) (check-equal-values? (parse "git://not-github.com/racket/fish" #f #f) (values "fish" 'git #t)) (check-equal-values? (parse "git://not-github.com/fish" #f #f) (values "fish" 'git #t)) @@ -129,6 +130,7 @@ (check-equal-values? (parse "git://not-github.com/.././" #f #rx"indicator") (values #f 'git #f)) (check-equal-values? (parse "git://not-github.com/racket/fish" 'clone #f) (values "fish" 'clone #t)) (check-equal-values? (parse "git://not-github.com/.././" 'clone #rx"indicator") (values #f 'clone #f)) + (check-equal-values? (parse "git://not-github.com/fish/?path=../bill" #f #rx"indicator") (values #f 'git #f)) (check-equal-values? (parse "http://racket-lang.org/racket/fish" 'git #f) (values "fish" 'git #t)) (check-equal-values? (parse "https://racket-lang.org/racket/fish" 'git #f) (values "fish" 'git #t)) diff --git a/racket/collects/pkg/name.rkt b/racket/collects/pkg/name.rkt index a97348382d..2620a7c7bd 100644 --- a/racket/collects/pkg/name.rkt +++ b/racket/collects/pkg/name.rkt @@ -196,6 +196,13 @@ (complain "URL path ends with a directory indicator")) (cor ((num-empty p) . < . 2) (complain "URL path ends with two empty elements")))) + (let ([a (assoc 'path (url-query url))]) + (or (not a) + (not (cdr a)) + (cor (for/and ([e (in-list (string-split (cdr a) "/"))]) + (not (or (equal? e ".") + (equal? e "..")))) + (complain "path query includes a directory indicator")))) (extract-git-name url p complain-name)) ;; github:// (let ([p (if (equal? "" (path/param-path (last p))) From c15d2f71d4ca568556c98a877eca771337eec5bd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 15:27:22 -0600 Subject: [PATCH 206/381] file/untar: fix handling of a broken tar file Closes #1049 --- pkgs/racket-test/tests/file/unpackers.rkt | 16 +++++++++++++++- racket/collects/file/untar.rkt | 9 +++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test/tests/file/unpackers.rkt b/pkgs/racket-test/tests/file/unpackers.rkt index 23d0fc7a36..43707ce389 100644 --- a/pkgs/racket-test/tests/file/unpackers.rkt +++ b/pkgs/racket-test/tests/file/unpackers.rkt @@ -174,8 +174,22 @@ (define (unzip-tests [preserve-timestamps? #f]) (when zip-exe (test do (run-tests (make-unzip-tests* preserve-timestamps?))))) +(define (untar-of-invalid-tests) + ;; Make sure we don't get an internal error for this misformatted tar file: + (define bad-tar.gz + (bytes-append #"\37\213\b\b!D\363U\0\3test.tar\0\355\321A\n\302@\f\205\341\254=\305\334\240\223qb\316\323" + #"\205]YZl\274\277V\21\334\210(\fR\370\277M\26\t\344\301\213\343\22\235\264\225o\334m\235" + #"\352\226_\347\223h1\257\207\252V\\\262j\325*\311\32\347\272\273,\321\237S\222q8\365\21\357" + #"\357>\3557*\326\376\207ij\371\343\321\277\177\321\377\336r\221T\272\30\347\326\341\350?v\377" + #"\16\1\0\0\0\0\0\0\0\0\0\0\0\0\340'W\327\1)\27\0(\0\0")) + (test (regexp-match? + #rx"^unt" + (with-handlers ([exn? exn-message]) + (untgz (open-input-bytes bad-tar.gz) #:filter (lambda args #f)))))) + (module+ main (tests)) (define (tests) (test do (untar-tests) do (unzip-tests) - do (unzip-tests #t))) + do (unzip-tests #t) + do (untar-of-invalid-tests))) diff --git a/racket/collects/file/untar.rkt b/racket/collects/file/untar.rkt index bce385eb9b..d524d4c1c3 100644 --- a/racket/collects/file/untar.rkt +++ b/racket/collects/file/untar.rkt @@ -162,10 +162,11 @@ ;; traditional: (define skip-tail (- len - (for/or ([i (in-range len 0 -1)]) - (case (integer->char (bytes-ref bstr (sub1 i))) - [(#\space #\nul) #f] - [else i])))) + (or (for/or ([i (in-range len 0 -1)]) + (case (integer->char (bytes-ref bstr (sub1 i))) + [(#\space #\nul) #f] + [else i])) + (error 'untar "bad number ~e at ~a" bstr (file-position in))))) (for/fold ([v 0]) ([i (in-range (- len skip-tail))]) (define b (bytes-ref bstr i)) (if (<= (char->integer #\0) b (char->integer #\7)) From c7fac6e98e3bc6aed2d94997c10e20dd89b070f3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 16:20:14 -0600 Subject: [PATCH 207/381] raco pkg catalog-archive: add a `--pkg-fail` option Relevant to #1032 --- pkgs/racket-doc/pkg/scribblings/pkg.scrbl | 9 +++++++++ racket/collects/pkg/main.rkt | 24 ++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl index a44ec11f21..4f58014a23 100644 --- a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -1026,6 +1026,15 @@ for @nonterm{key}. @item{@DFlag{version} @nonterm{version} or @Flag{v} @nonterm{version} --- Copies catalog results specific to @nonterm{version} (for catalogs that make a distinction), instead of the installation's Racket version.} + @item{@DFlag{pkg-fail} @nonterm{mode} --- Determines handling of failure for an individual + package, such as when a @nonterm{src-catalog} contains a bad package source. The + following @nonterm{mode}s are available: + @itemlist[ + @item{@exec{fail} (the default) --- archiving stops and fails;} + @item{@exec{skip} --- the package is skipped and omitted from the archive catalog; or} + @item{@exec{continue} --- like @exec{skip}, but @exec{raco pkg catalog-archive} + exits with a status code of @exec{5} if any package was skipped.} + ]} ] @history[#:added "6.0.17"] diff --git a/racket/collects/pkg/main.rkt b/racket/collects/pkg/main.rkt index 80de6f299c..a658d357c6 100644 --- a/racket/collects/pkg/main.rkt +++ b/racket/collects/pkg/main.rkt @@ -581,15 +581,37 @@ [(#:str state-database #f) state () "Read/write as state of "] [(#:str vers #f) version ("-v") "Copy information suitable for Racket "] [#:bool relative () "Make source paths relative when possible"] + [(#:sym mode [fail ignore continue] 'fail) pkg-fail () + ("Select handling of package-download failure;" + "s: fail (the default), skip, continue (but with exit status of 5)")] #:args (dest-dir . src-catalog) (parameterize ([current-pkg-error (pkg-error 'catalog-archive)] [current-pkg-lookup-version (or version (current-pkg-lookup-version))]) + (define fail-at-end? #f) (pkg-catalog-archive dest-dir src-catalog #:from-config? from-config #:state-catalog state - #:relative-sources? relative))] + #:relative-sources? relative + #:package-exn-handler (case pkg-fail + [(fail) (lambda (name exn) (raise exn))] + [(skip continue) + (lambda (name exn) + (log-error (~a "archiving failed for package; ~a\n" + " package name: ~a\n" + " original error:\n~a") + (if (eq? pkg-fail 'continue) + "continuing" + "skipping") + name + (regexp-replace* #rx"(?m:^)" + (exn-message exn) + " ")) + (when (eq? pkg-fail 'continue) + (set! fail-at-end? #t)))])) + (when fail-at-end? + (exit 5)))] ;; ---------------------------------------- [archive "Create catalog from installed packages" From 0d3b5b61f0181e74fa1a7f4b5c018cd8c6682fc9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 16:52:36 -0600 Subject: [PATCH 208/381] untar, untgz, and unzip: add `#:permissive?` Also, strengthen the checking that `#:permissive?` (off by default) performs for `untar` and `untgz` to disallow a link whose target is an absolute path or has an up-directory element. --- pkgs/racket-doc/file/scribblings/untar.scrbl | 11 ++++++++- pkgs/racket-doc/file/scribblings/untgz.scrbl | 5 +++- pkgs/racket-doc/file/scribblings/unzip.scrbl | 11 ++++++++- pkgs/racket-test/tests/file/unpackers.rkt | 24 ++++++++++++++++++-- racket/collects/file/private/check-path.rkt | 11 +++++---- racket/collects/file/untar.rkt | 12 +++++++--- racket/collects/file/untgz.rkt | 4 +++- racket/collects/file/unzip.rkt | 6 +++-- 8 files changed, 68 insertions(+), 16 deletions(-) diff --git a/pkgs/racket-doc/file/scribblings/untar.scrbl b/pkgs/racket-doc/file/scribblings/untar.scrbl index b055ddd77b..7987015795 100644 --- a/pkgs/racket-doc/file/scribblings/untar.scrbl +++ b/pkgs/racket-doc/file/scribblings/untar.scrbl @@ -9,6 +9,7 @@ a function to extract items from a TAR/USTAR archive.} @defproc[(untar [in (or/c path-string? input-port?)] [#:dest dest-path (or/c path-string? #f) #f] [#:strip-count strip-count exact-nonnegative-integer? 0] + [#:permissive? permissive? any/c #f] [#:filter filter-proc (path? (or/c path? #f) symbol? exact-integer? (or/c path? #f) @@ -28,6 +29,12 @@ elements are removed from the item path from the archive (before prefixing the path with @racket[dest-path]); if the item's path contains @racket[strip-count] elements, then it is not extracted. +Unless @racket[permissive?] is true, then archive items with paths containing +an up-directory indicator are disallowed, and a link item whose target +is an absolute path or contains an up-directory indicator is also +disallowed. Absolute paths are always disallowed. A disallowed +path triggers an exception. + For each item in the archive, @racket[filter-proc] is applied to @itemlist[ @@ -60,4 +67,6 @@ For each item in the archive, @racket[filter-proc] is applied to ] If the result of @racket[filter-proc] is @racket[#f], then the item is -not unpacked.} +not unpacked. + +@history[#:changed "6.2.900.17" @elem{Added the @racket[#:permissive?] argument.}]} diff --git a/pkgs/racket-doc/file/scribblings/untgz.scrbl b/pkgs/racket-doc/file/scribblings/untgz.scrbl index 4be9ee0ed0..479865af2e 100644 --- a/pkgs/racket-doc/file/scribblings/untgz.scrbl +++ b/pkgs/racket-doc/file/scribblings/untgz.scrbl @@ -11,6 +11,7 @@ a function to extract items from a possible @exec{gzip}ped TAR/USTAR archive.} @defproc[(untgz [in (or/c path-string? input-port?)] [#:dest dest-path (or/c path-string? #f) #f] [#:strip-count strip-count exact-nonnegative-integer? 0] + [#:permissive? permissive? any/c #f] [#:filter filter-proc (path? (or/c path? #f) symbol? exact-integer? (or/c path? #f) @@ -21,4 +22,6 @@ a function to extract items from a possible @exec{gzip}ped TAR/USTAR archive.} void?]{ The same as @racket[untar], but if @racket[in] is in @exec{gzip} form, -it is @racket[gunzip]ped as it is unpacked.} +it is @racket[gunzip]ped as it is unpacked. + +@history[#:changed "6.2.900.17" @elem{Added the @racket[#:permissive?] argument.}]} diff --git a/pkgs/racket-doc/file/scribblings/unzip.scrbl b/pkgs/racket-doc/file/scribblings/unzip.scrbl index 9db4d7e0f0..d3c619c8af 100644 --- a/pkgs/racket-doc/file/scribblings/unzip.scrbl +++ b/pkgs/racket-doc/file/scribblings/unzip.scrbl @@ -50,6 +50,7 @@ directory while returning the result of @racket[proc]. @defproc[(make-filesystem-entry-reader [#:dest dest-path (or/c path-string? #f) #f] [#:strip-count strip-count exact-nonnegative-integer? 0] + [#:permissive? permissive? any/c #f] [#:exists exists (or/c 'skip 'error 'replace 'truncate 'truncate/replace 'append 'update 'can-update 'must-truncate) @@ -72,13 +73,21 @@ elements are removed from the entry path from the archive (before prefixing the path with @racket[dest-path]); if the item's path contains @racket[strip-count] elements, then it is not extracted. +Unless @racket[permissive?] is true, then entries with paths containing +an up-directory indicator are disallowed, and a link entry whose target +is an absolute path or contains an up-directory indicator is also +disallowed. Absolute paths are always disallowed. A disallowed +path triggers an exception. + If @racket[exists] is @racket['skip] and the file for an entry already exists, then the entry is skipped. Otherwise, @racket[exists] is passed on to @racket[open-output-file] for writing the entry's inflated content. @history[#:changed "6.0.0.3" - @elem{Added support for the optional timestamp argument in the result function.}]} + @elem{Added support for the optional timestamp argument in the result function.} + #:changed "6.2.900.17" + @elem{Added the @racket[#:permissive?] argument.}]} @defproc[(read-zip-directory [in (or/c path-string? input-port?)]) zip-directory?]{ diff --git a/pkgs/racket-test/tests/file/unpackers.rkt b/pkgs/racket-test/tests/file/unpackers.rkt index 43707ce389..e30c852c09 100644 --- a/pkgs/racket-test/tests/file/unpackers.rkt +++ b/pkgs/racket-test/tests/file/unpackers.rkt @@ -98,7 +98,6 @@ (delete-directory/files "sub") (file-or-directory-permissions* more-dir "rwx") - ;; make sure top-level file extraction works (untgz (open-input-bytes ;; bytes gotten from 'tar' and 'gzip' command-line tools @@ -112,7 +111,28 @@ (test (file-exists? "L1c")) (test (file-exists? "helper.rkt")) (delete-file "L1c") - (delete-file "helper.rkt")) + (delete-file "helper.rkt") + + ;; check on [non-]permissive unpacking + (unless (eq? (system-type) 'windows) + (for ([target (in-list '("../x" "/tmp/abs" "ok"))]) + (define ok? (equal? target "ok")) + (make-directory* "ex2") + (make-file-or-directory-link target (build-path "ex2" "link")) + (tar "ex2" a.tar) + (make-directory "sub") + (test (with-handlers ([exn:fail? (lambda (exn) + (regexp-match? #rx"up-directory|absolute" (exn-message exn)))]) + (untar "a.tar" #:dest "sub") + ok?)) + (test (equal? ok? (link-exists? (build-path "sub" "ex2" "link")))) + (delete-directory/files "sub") + + (make-directory "sub") + (untar "a.tar" #:dest "sub" #:permissive? #t) + (test (link-exists? (build-path "sub" "ex2" "link"))) + (delete-directory/files "sub") + (delete-directory/files "ex2")))) (define ((make-unzip-tests* preserve-timestamps?)) (make-directory* "ex1") diff --git a/racket/collects/file/private/check-path.rkt b/racket/collects/file/private/check-path.rkt index 90a4d219ab..15e1ef10a6 100644 --- a/racket/collects/file/private/check-path.rkt +++ b/racket/collects/file/private/check-path.rkt @@ -2,10 +2,11 @@ (provide check-unpack-path) -(define (check-unpack-path who filename) +(define (check-unpack-path who filename + #:allow-up? [allow-up? #f]) (when (absolute-path? filename) (error who "won't extract a file with an absolute path\n path: ~e" filename)) - (for ([e (in-list (explode-path filename))]) - (when (eq? e 'up) - (error who "won't extract a file with an up-directory element\n path: ~e" filename)))) - + (unless allow-up? + (for ([e (in-list (explode-path filename))]) + (when (eq? e 'up) + (error who "won't extract a file with an up-directory element\n path: ~e" filename))))) diff --git a/racket/collects/file/untar.rkt b/racket/collects/file/untar.rkt index d524d4c1c3..c0fd1c7e1f 100644 --- a/racket/collects/file/untar.rkt +++ b/racket/collects/file/untar.rkt @@ -11,6 +11,7 @@ (#:dest (or/c #f path-string?) #:strip-count exact-nonnegative-integer? + #:permissive? any/c #:filter (path? (or/c path? #f) symbol? exact-integer? (or/c path? #f) exact-nonnegative-integer? exact-nonnegative-integer? @@ -22,6 +23,7 @@ (define (untar in #:dest [dest #f] #:strip-count [strip-count 0] + #:permissive? [permissive? #f] #:filter [filter void]) ((if (input-port? in) (lambda (in f) (f in)) @@ -34,7 +36,8 @@ (for ([delay (in-list (reverse delays))]) (delay)) (loop (untar-one-from-port in delays - dest strip-count filter))))))) + dest strip-count filter + permissive?))))))) (define (read-bytes* n in) (define s (read-bytes n in)) @@ -44,7 +47,8 @@ s) (define (untar-one-from-port in delays - dest strip-count filter) + dest strip-count filter + permissive?) (define name-bytes (read-bytes* 100 in)) (define mode (tar-bytes->number (read-bytes* 8 in) in)) (define owner (tar-bytes->number (read-bytes* 8 in) in)) @@ -79,7 +83,7 @@ name (bytes-append prefix #"/" name))) name)))) - (check-unpack-path 'untar base-filename) + (check-unpack-path 'untar base-filename #:allow-up? permissive?) (define stripped-filename (strip-prefix base-filename strip-count)) (define filename (and stripped-filename (if dest @@ -87,6 +91,8 @@ stripped-filename))) (define link-target (and (eq? type 'link) (bytes->path (nul-terminated link-target-bytes)))) + (when (and link-target (not permissive?)) + (check-unpack-path 'untar link-target)) (read-bytes* 12 in) ; padding (define create? (filter base-filename filename type size link-target mod-time mode)) diff --git a/racket/collects/file/untgz.rkt b/racket/collects/file/untgz.rkt index d8fac6e2c0..592eef7850 100644 --- a/racket/collects/file/untgz.rkt +++ b/racket/collects/file/untgz.rkt @@ -11,6 +11,7 @@ (#:dest (or/c #f path-string?) #:strip-count exact-nonnegative-integer? + #:permissive? any/c #:filter (path? (or/c path? #f) symbol? exact-integer? (or/c path? #f) exact-nonnegative-integer? exact-nonnegative-integer? @@ -20,6 +21,7 @@ (define (untgz in #:dest [dest #f] #:strip-count [strip-count 0] + #:permissive? [permissive? #f] #:filter [filter void]) ((if (input-port? in) (lambda (in f) (f in)) @@ -44,7 +46,7 @@ (thread-wait t)))] [else (values in void)])) (begin0 - (untar in2 #:dest dest #:strip-count strip-count #:filter filter) + (untar in2 #:dest dest #:strip-count strip-count #:permissive? permissive? #:filter filter) (wait))))) diff --git a/racket/collects/file/unzip.rkt b/racket/collects/file/unzip.rkt index 189afcf059..ef59ef681c 100644 --- a/racket/collects/file/unzip.rkt +++ b/racket/collects/file/unzip.rkt @@ -25,6 +25,8 @@ (or/c #f path-string?) #:strip-count exact-nonnegative-integer? + #:permissive? + any/c #:exists (or/c 'skip 'error 'replace 'truncate 'truncate/replace 'append 'update @@ -358,10 +360,10 @@ ;; make-filesystem-entry-reader : [output-flag] -> (bytes boolean input-port -> any) (define make-filesystem-entry-reader - (lambda (#:dest [dest-dir #f] #:strip-count [strip-count 0] #:exists [flag 'error]) + (lambda (#:dest [dest-dir #f] #:strip-count [strip-count 0] #:permissive? [permissive? #f] #:exists [flag 'error]) (lambda (name dir? in [timestamp #f]) (define path (bytes->path name)) - (check-unpack-path 'unzip path) + (check-unpack-path 'unzip path #:allow-up? permissive?) (let* ([base-path (strip-prefix path strip-count)] [path (and base-path (if dest-dir From 17d69338a90c938faa3bd2722c83551d160cdf5b Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 10 Sep 2015 16:36:57 -0400 Subject: [PATCH 209/381] Remove obselete time config defines. Removes `USE_FTIME`, `USE_PALMTIME`, `USE_MACTIME`, `TIME_SYNTAX`. --- racket/src/racket/sconfig.h | 12 +-- racket/src/racket/src/fun.c | 138 ++++++++------------------------ racket/src/racket/src/schpriv.h | 2 - racket/src/racket/src/struct.c | 7 -- racket/src/racket/uconfig.h | 1 - 5 files changed, 36 insertions(+), 124 deletions(-) diff --git a/racket/src/racket/sconfig.h b/racket/src/racket/sconfig.h index f308a5aa76..87eca16d2b 100644 --- a/racket/src/racket/sconfig.h +++ b/racket/src/racket/sconfig.h @@ -37,7 +37,6 @@ # define UNIX_FILE_SYSTEM # define NO_UNIX_USERS -# define TIME_SYNTAX # define DIR_FUNCTION # define DIRENT_NO_NAMLEN # define GETENV_FUNCTION @@ -648,7 +647,6 @@ # define MKDIR_NO_MODE_FLAG # endif -# define TIME_SYNTAX # define USE_WIN32_TIME # define WINDOWS_GET_PROCESS_TIMES # define GETENV_FUNCTION @@ -1043,18 +1041,12 @@ /* Language Features */ /*********************/ - /* TIME_SYNTAX adds the (time ...) syntax; this may need to be - turned off for compilation on some systems. - CLOCKS_PER_SEC relates the values returned by clock() to + /* CLOCKS_PER_SEC relates the values returned by clock() to real seconds. (The difference between two clock() calls is divided by this number.) Usually, this is defined in ; it defaults to 1000000 */ - /* USE_FTIME uses ftime instead of gettimeofday; only for TIME_SYNTAX */ - - /* USE_PLAIN_TIME uses time; only for TIME_SYNTAX */ - - /* USE_MACTIME uses the Mac toolbox to implement time functions. */ + /* USE_PLAIN_TIME uses time. */ /* USE_WIN32_TIME uses the Win32 API to implement time functions. */ diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 8e3a9123c0..644e8da8af 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -35,41 +35,33 @@ /* The implementations of the time primitives, such as `current-seconds', vary a lot from platform to platform. */ -#ifdef TIME_SYNTAX -# ifdef USE_WIN32_TIME -# include -# else -# ifndef USE_PALMTIME -# if defined(OSKIT) && !defined(OSKIT_TEST) - /* Get FreeBSD version, not oskit/time.h version */ -# include -# endif -# include -# ifdef USE_FTIME -# include -# else -# include -# endif /* USE_FTIME */ -# ifdef USE_GETRUSAGE -# include -# include -# include -# include -# endif /* USE_GETRUSAGE */ -# ifdef USE_SYSCALL_GETRUSAGE -# include -# define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b) -# define USE_GETRUSAGE -# endif /* USE_SYSCALL_GETRUSAGE */ -# ifdef WINDOWS_GET_PROCESS_TIMES -# include -# endif -# if !defined(USE_GETRUSAGE) && !defined(WINDOWS_GET_PROCESS_TIMES) && !defined(USER_TIME_IS_CLOCK) -# include -# endif -# endif /* USE_PALMTIME */ -# endif /* USE_MACTIME */ -#endif /* TIME_SYNTAX */ +#ifdef USE_WIN32_TIME +# include +#else +# if defined(OSKIT) && !defined(OSKIT_TEST) + /* Get FreeBSD version, not oskit/time.h version */ +# include +# endif +# include +# include +# ifdef USE_GETRUSAGE +# include +# include +# include +# include +# endif /* USE_GETRUSAGE */ +# ifdef USE_SYSCALL_GETRUSAGE +# include +# define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b) +# define USE_GETRUSAGE +# endif /* USE_SYSCALL_GETRUSAGE */ +# ifdef WINDOWS_GET_PROCESS_TIMES +# include +# endif +# if !defined(USE_GETRUSAGE) && !defined(WINDOWS_GET_PROCESS_TIMES) && !defined(USER_TIME_IS_CLOCK) +# include +# endif +#endif /* USE_WIN32_TIME */ static void ASSERT_SUSPEND_BREAK_ZERO() { #if 0 @@ -172,7 +164,6 @@ static Scheme_Object *call_with_immediate_cc_mark (int argc, Scheme_Object *argv static Scheme_Object *void_func (int argc, Scheme_Object *argv[]); static Scheme_Object *void_p (int argc, Scheme_Object *argv[]); static Scheme_Object *dynamic_wind (int argc, Scheme_Object *argv[]); -#ifdef TIME_SYNTAX static Scheme_Object *time_apply(int argc, Scheme_Object *argv[]); static Scheme_Object *current_milliseconds(int argc, Scheme_Object **argv); static Scheme_Object *current_inexact_milliseconds(int argc, Scheme_Object **argv); @@ -180,7 +171,6 @@ static Scheme_Object *current_process_milliseconds(int argc, Scheme_Object **arg static Scheme_Object *current_gc_milliseconds(int argc, Scheme_Object **argv); static Scheme_Object *current_seconds(int argc, Scheme_Object **argv); static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv); -#endif static Scheme_Object *object_name(int argc, Scheme_Object *argv[]); static Scheme_Object *procedure_arity(int argc, Scheme_Object *argv[]); static Scheme_Object *procedure_arity_p(int argc, Scheme_Object *argv[]); @@ -515,7 +505,6 @@ scheme_init_fun (Scheme_Env *env) | SCHEME_PRIM_IS_OMITABLE); scheme_add_global_constant("void?", scheme_void_p_proc, env); -#ifdef TIME_SYNTAX scheme_add_global_constant("time-apply", scheme_make_prim_w_arity2(time_apply, "time-apply", @@ -552,7 +541,6 @@ scheme_init_fun (Scheme_Env *env) "seconds->date", 1, 2), env); -#endif scheme_add_global_constant("dynamic-wind", scheme_make_prim_w_arity(dynamic_wind, @@ -9417,8 +9405,6 @@ static Scheme_Object *jump_to_alt_continuation() /* time */ /*========================================================================*/ -#ifdef TIME_SYNTAX - #ifndef CLOCKS_PER_SEC #define CLOCKS_PER_SEC 1000000 #endif @@ -9442,22 +9428,12 @@ intptr_t scheme_get_milliseconds(void) XFORM_SKIP_PROC /* this function can be called from any OS thread */ { -#ifdef USE_MACTIME - return scheme_get_process_milliseconds(); -#else -# ifdef USE_FTIME - struct MSC_IZE(timeb) now; - MSC_IZE(ftime)(&now); - return (intptr_t)(now.time * 1000 + now.millitm); -# else -# ifdef USE_WIN32_TIME +#ifdef USE_WIN32_TIME return (intptr_t)(get_hectonanoseconds_as_longlong() / (mzlonglong)10000); -# else +#else struct timeval now; gettimeofday(&now, NULL); return now.tv_sec * 1000 + now.tv_usec / 1000; -# endif -# endif #endif } @@ -9465,32 +9441,15 @@ double scheme_get_inexact_milliseconds(void) XFORM_SKIP_PROC /* this function can be called from any OS thread */ { -#ifdef USE_MACTIME - { - /* This is wrong, since it's not since January 1, 1970 */ - UnsignedWide time; - Microseconds(&time); - return (((double)(time.lo >> 10) - + ((double)(time.hi >> 10) * 4294967296.0)) - * 1.024); - } -#else -# ifdef USE_FTIME - struct MSC_IZE(timeb) now; - MSC_IZE(ftime)(&now); - return (double)now.time * 1000.0 + (double)now.millitm; -# else -# ifdef USE_WIN32_TIME +#ifdef USE_WIN32_TIME FILETIME ft; mzlonglong v; v = get_hectonanoseconds_as_longlong(); return (double)(v / 10000) + (((double)(v % 10000)) / 10000.0); -# else +#else struct timeval now; gettimeofday(&now, NULL); return (double)now.tv_sec * 1000.0 + (double)now.tv_usec / 1000; -# endif -# endif #endif } @@ -9514,14 +9473,7 @@ intptr_t scheme_get_process_milliseconds(void) return s * 1000 + u / 1000; # else -# ifdef USE_MACTIME - { - UnsignedWide time; - Microseconds(&time); - return ((uintptr_t)time.lo) / 1000; - } -# else -# ifdef WINDOWS_GET_PROCESS_TIMES +# ifdef WINDOWS_GET_PROCESS_TIMES { FILETIME cr, ex, kr, us; if (GetProcessTimes(GetCurrentProcess(), &cr, &ex, &kr, &us)) { @@ -9532,9 +9484,8 @@ intptr_t scheme_get_process_milliseconds(void) } else return 0; /* anything better to do? */ } -# else +# else return clock() * 1000 / CLOCKS_PER_SEC; -# endif # endif # endif @@ -9591,14 +9542,6 @@ intptr_t scheme_get_seconds(void) #ifdef USE_WIN32_TIME return (intptr_t)(get_hectonanoseconds_as_longlong() / (mzlonglong)10000000); #else -# ifdef USE_PALMTIME - return TimGetSeconds(); -# else -# ifdef USE_FTIME - struct MSC_IZE(timeb) now; - MSC_IZE(ftime)(&now); - return (intptr_t)now.time; -# else # ifdef USE_PLAIN_TIME time_t now; now = time(NULL); @@ -9607,8 +9550,6 @@ intptr_t scheme_get_seconds(void) struct timeval now; gettimeofday(&now, NULL); return now.tv_sec; -# endif -# endif # endif #endif } @@ -9737,13 +9678,8 @@ static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv) # define CHECK_TIME_T uintptr_t SYSTEMTIME localTime; #else -# ifdef USE_PALMTIME -# define CHECK_TIME_T UInt32 - DateTimeType localTime; -# else -# define CHECK_TIME_T time_t +# define CHECK_TIME_T time_t struct tm *localTime; -# endif #endif CHECK_TIME_T now; char *tzn; @@ -9799,15 +9735,11 @@ static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv) } } #else -# ifdef USE_PALMTIME - TimSecondsToDateTime(lnow, &localTime) ; -# else if (get_gmt) localTime = gmtime(&now); else localTime = localtime(&now); success = !!localTime; -# endif #endif if (success) { @@ -10046,8 +9978,6 @@ static Scheme_Object *current_seconds(int argc, Scheme_Object **argv) return scheme_make_integer_value_from_time(secs); } -#endif - /*========================================================================*/ /* read-eval-print */ diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index fb8ce29794..ee7d129c48 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -508,9 +508,7 @@ extern Scheme_Object *scheme_write_proc, *scheme_display_proc, *scheme_print_pro extern Scheme_Object *scheme_raise_arity_error_proc; -#ifdef TIME_SYNTAX extern Scheme_Object *scheme_date; -#endif extern Scheme_Object *scheme_liberal_def_ctx_type; diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index 353885cbc1..dd07614798 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -249,11 +249,9 @@ scheme_init_struct (Scheme_Env *env) Scheme_Object **as_names; Scheme_Object **as_values; int as_count; -#ifdef TIME_SYNTAX Scheme_Object **ts_names; Scheme_Object **ts_values; int ts_count; -#endif Scheme_Object **loc_names; Scheme_Object **loc_values; int loc_count; @@ -261,12 +259,10 @@ scheme_init_struct (Scheme_Env *env) Scheme_Object *guard; READ_ONLY static const char *arity_fields[1] = { "value" }; -#ifdef TIME_SYNTAX READ_ONLY static const char *date_fields[10] = { "second", "minute", "hour", "day", "month", "year", "week-day", "year-day", "dst?", "time-zone-offset" }; READ_ONLY static const char *date_star_fields[2] = { "nanosecond", "time-zone-name" }; -#endif READ_ONLY static const char *location_fields[10] = { "source", "line", "column", "position", "span" }; #ifdef MZ_PRECISE_GC @@ -290,7 +286,6 @@ scheme_init_struct (Scheme_Env *env) env); } -#ifdef TIME_SYNTAX /* Add date structure: */ REGISTER_SO(scheme_date); scheme_date = scheme_make_struct_type_from_string("date", NULL, 10, NULL, @@ -323,8 +318,6 @@ scheme_init_struct (Scheme_Env *env) } -#endif - /* Add location structure: */ REGISTER_SO(location_struct); location_struct = scheme_make_struct_type_from_string("srcloc", NULL, 5, NULL, diff --git a/racket/src/racket/uconfig.h b/racket/src/racket/uconfig.h index f3bb77e608..e2fbe76b2d 100644 --- a/racket/src/racket/uconfig.h +++ b/racket/src/racket/uconfig.h @@ -5,7 +5,6 @@ #define SYSTEM_TYPE_NAME "unix" #define UNIX_FILE_SYSTEM -#define TIME_SYNTAX #define PROCESS_FUNCTION #define DIR_FUNCTION #define GETENV_FUNCTION From 78fc476e61ee1854d836e622f247f70b8495cff1 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 10 Sep 2015 18:35:40 -0400 Subject: [PATCH 210/381] Reject relative paths in MANIFEST files when installing. --- racket/collects/pkg/private/stage.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/racket/collects/pkg/private/stage.rkt b/racket/collects/pkg/private/stage.rkt index 8f3fd17975..52bc8d457b 100644 --- a/racket/collects/pkg/private/stage.rkt +++ b/racket/collects/pkg/private/stage.rkt @@ -11,6 +11,7 @@ net/url file/untgz file/unzip + file/private/check-path openssl/sha1 json net/git-checkout @@ -412,6 +413,7 @@ pkg-name) 'directory)) (define (path-like f) + (check-unpack-path 'MANIFEST f) (build-path package-path f)) (define (url-like f) (if (and (pair? (url-path pkg-url)) From 181edfeec6c32ff1e0a4eeed5bab440fa42a4704 Mon Sep 17 00:00:00 2001 From: Anthony Carrico Date: Thu, 10 Sep 2015 14:46:31 -0400 Subject: [PATCH 211/381] Format string and arguments match. --- racket/collects/racket/private/kw.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/racket/private/kw.rkt b/racket/collects/racket/private/kw.rkt index 9f6a360a63..98a85577f3 100644 --- a/racket/collects/racket/private/kw.rkt +++ b/racket/collects/racket/private/kw.rkt @@ -1040,7 +1040,7 @@ (if s (if l (format "~a:~a:~a: " s l c) - (format "~a:::~a: " s l p)) + (format "~a:::~a: " s p)) "")) msg (syntax-e #'self)) From 390e69fac5daa58198187b987d0024d488d5ad4a Mon Sep 17 00:00:00 2001 From: Anthony Carrico Date: Fri, 11 Sep 2015 20:35:52 -0400 Subject: [PATCH 212/381] Test format string and arguments mismatch error. --- pkgs/racket-test-core/tests/racket/syntax.rktl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/syntax.rktl b/pkgs/racket-test-core/tests/racket/syntax.rktl index 3d3b789616..bb2dc38bae 100644 --- a/pkgs/racket-test-core/tests/racket/syntax.rktl +++ b/pkgs/racket-test-core/tests/racket/syntax.rktl @@ -1943,6 +1943,15 @@ (datum->syntax #f 'same)) 'x)))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check error formatting from the keyword-argument lambda layer. + +(let () + (define l (make-log-receiver (current-logger) 'warning)) + (test #t + procedure? + (eval (datum->syntax #'here '(lambda () (sort '(1))) (list 'a #f #f #f #f))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) From 4f5d8da278d3c0a8a8aae17363a38e1ce0dc1b9e Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Sat, 12 Sep 2015 01:08:31 +0200 Subject: [PATCH 213/381] Fix "require" in racket-benchmarks/places/symbols.rkt --- .../tests/racket/benchmarks/places/symbols.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-benchmarks/tests/racket/benchmarks/places/symbols.rkt b/pkgs/racket-benchmarks/tests/racket/benchmarks/places/symbols.rkt index 049dd387e4..8df2ea7ec2 100644 --- a/pkgs/racket-benchmarks/tests/racket/benchmarks/places/symbols.rkt +++ b/pkgs/racket-benchmarks/tests/racket/benchmarks/places/symbols.rkt @@ -10,7 +10,7 @@ (module pct1 racket/base (require racket/place racket/match - "place-utils.rkt") + tests/racket/place-utils) (provide place-main) (define (place-main ch) @@ -48,7 +48,7 @@ END #< Date: Tue, 28 Jul 2015 15:52:10 +0200 Subject: [PATCH 214/381] Fix match with (list-no-order p ..k) patterns p ..k matches exactly k repetitions of p, but its documented behavior is to match "k or more" repetitions. This fix implements the documented behavior. Fixes bug number 15122. --- pkgs/racket-test/tests/match/examples.rkt | 20 ++++++++++++++++++++ racket/collects/racket/match/parse.rkt | 3 +-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/match/examples.rkt b/pkgs/racket-test/tests/match/examples.rkt index 618744d638..036aa9bbd9 100644 --- a/pkgs/racket-test/tests/match/examples.rkt +++ b/pkgs/racket-test/tests/match/examples.rkt @@ -202,6 +202,26 @@ [(list-no-order 1 2 3 rest ...) rest] [_ 'no])) + (comp '(x y z) + (match '(1 x 2 y 3 z) + [(list-no-order 1 2 3 rest ..1) rest] + [_ 'no])) + + (comp '(x y z) + (match '(1 x 2 y 3 z) + [(list-no-order 1 2 3 rest ..2) rest] + [_ 'no])) + + (comp '(x y z) + (match '(1 x 2 y 3 z) + [(list-no-order 1 2 3 rest ..3) rest] + [_ 'no])) + + (comp 'no + (match '(1 x 2 y 3 z) + [(list-no-order 1 2 3 rest ..4) rest] + [_ 'no])) + (comp 'yes (match '(a (c d)) diff --git a/racket/collects/racket/match/parse.rkt b/racket/collects/racket/match/parse.rkt index 9804a7f853..116b2df974 100644 --- a/racket/collects/racket/match/parse.rkt +++ b/racket/collects/racket/match/parse.rkt @@ -101,12 +101,11 @@ (ddk? #'dd) (let* ([count (ddk? #'dd)] [min (if (number? count) count #f)] - [max (if (number? count) count #f)] [ps (syntax->list #'(p ...))]) (GSeq (cons (list (rearm+parse #'lp)) (for/list ([p ps]) (list (parse p)))) (cons min (map (lambda _ 1) ps)) - (cons max (map (lambda _ 1) ps)) + (cons #f (map (lambda _ 1) ps)) ;; vars in lp are lists, vars elsewhere are not (cons #f (map (lambda _ #t) ps)) (Null (Dummy (syntax/loc stx _))) From 58895067c87523c88cbd1b8445b1e26c1651afd4 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Fri, 11 Sep 2015 22:01:29 -0300 Subject: [PATCH 215/381] Remove nested begin0's added by sfs pass --- .../tests/racket/optimize.rktl | 29 +++++++++++++ racket/src/racket/src/sfs.c | 41 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 6ee590e510..3e0b06e36f 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -4270,6 +4270,35 @@ (eval (read (open-input-bytes (get-output-bytes o2))))) exn:fail:read?)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; make sure sfs pass doesn't add a nested begin0 +;; to clear the variables used in the first expression + +(let () + (define c + '(module c racket/base + (define z (let ([result (random)]) + (begin0 (lambda () result) (newline)))))) + + (define o (open-output-bytes)) + + (parameterize ([current-namespace (make-base-namespace)]) + (write (compile c) o)) + + (define m (zo-parse (open-input-bytes (get-output-bytes o)))) + + ; extract the content of the begin0 expression + (define (analyze-beg0 m) + (define def-z (car (mod-body (compilation-top-code m)))) + (define body-z (let-one-body (def-values-rhs def-z))) + (define expr-z (car (beg0-seq body-z))) + (cond + [(lam? expr-z) 'ok] + [(beg0? expr-z) 'not-reduced-beg0-in-sfs] + [else 'unexpected])) + + (test 'ok (lambda () (analyze-beg0 m)))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; make sure `begin0' propertly propagates "multiple results" flags diff --git a/racket/src/racket/src/sfs.c b/racket/src/racket/src/sfs.c index 99daeace50..69b5294ec0 100644 --- a/racket/src/racket/src/sfs.c +++ b/racket/src/racket/src/sfs.c @@ -1023,6 +1023,44 @@ static Scheme_Object *bangboxenv_sfs(Scheme_Object *data, SFS_Info *info) } } +static Scheme_Object *flatten_begin0(Scheme_Object *o) +{ + /* At this point, we sometimes have (begin0 (begin0 (begin0 ...) ...)). + Flatten those out. */ + Scheme_Sequence *s = (Scheme_Sequence *)o, *s2; + int i, extra = 0; + + o = s->array[0]; + + while (SAME_TYPE(SCHEME_TYPE(o), scheme_begin0_sequence_type)) { + s2 = (Scheme_Sequence *)o; + extra += s2->count - 1; + o = s2->array[0]; + } + + if (extra) { + s2 = scheme_malloc_sequence(s->count + extra); + s2->so.type = scheme_begin0_sequence_type; + s2->count = s->count + extra; + + extra = s2->count -1; + o = (Scheme_Object *)s; + while (SAME_TYPE(SCHEME_TYPE(o), scheme_begin0_sequence_type)) { + s = (Scheme_Sequence *)o; + for (i = s->count - 1; i ; i--) { + s2->array[extra--] = s->array[i]; + } + o = s->array[i]; + } + s2->array[extra--] = o; + + if (extra != -1) scheme_signal_error("internal error: flatten begin0 failed"); + + return (Scheme_Object *)s2; + } else + return (Scheme_Object *)s; +} + static Scheme_Object * begin0_sfs(Scheme_Object *obj, SFS_Info *info) { @@ -1038,6 +1076,9 @@ begin0_sfs(Scheme_Object *obj, SFS_Info *info) ((Scheme_Sequence *)obj)->array[i] = le; } + if (info->pass) + obj = flatten_begin0(obj); + return obj; } From 5401c5d179d3574e6169823293b6cc045f8c010e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 12 Sep 2015 13:21:04 -0600 Subject: [PATCH 216/381] racket/sandbox docs: clarify that collection modules are accessible --- pkgs/racket-doc/scribblings/reference/sandbox.scrbl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/sandbox.scrbl b/pkgs/racket-doc/scribblings/reference/sandbox.scrbl index 5f49c1ffbb..45d8b6a43b 100644 --- a/pkgs/racket-doc/scribblings/reference/sandbox.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sandbox.scrbl @@ -47,7 +47,8 @@ function for further evaluation. The returned evaluator operates in an isolated and limited environment. In particular, filesystem access is restricted, which may -interfere with using modules from the filesystem. See below for +interfere with using modules from the filesystem that are not +in a @tech{collection}. See below for information on the @racket[allow-for-require], @racket[allow-for-load], and @racket[allow-read] arguments. When @racket[language] is a module path or when @racket[requires] is @@ -210,15 +211,17 @@ create the sandbox is higher than the limit, then The @racket[allow-for-require] and @racket[allow-for-load] arguments adjust filesystem permissions to extend the set of files that -are usable by the evaluator. The @racket[allow-for-require] argument lists -modules that can be @racket[require]d along with their imports -(transitively). The @racket[allow-for-load] argument lists files that can +are usable by the evaluator. Modules that are in a collection +are automatically accessible, but the @racket[allow-for-require] argument lists +additional modules that can be @racket[require]d along with their imports +(transitively) through a filesystem path. The @racket[allow-for-load] argument +similarly lists files that can be @racket[load]ed. (The precise permissions needed for @racket[require] versus @racket[load] can differ.) The @racket[allow-read] argument is for backward compatibility, only; each @racket[module-path?] element of @racket[allow-read] is effectively moved to @racket[allow-for-require], while other elements are moved to -@racket[all-for-load]. +@racket[allow-for-load]. The sandboxed environment is well isolated, and the evaluator function essentially sends it an expression and waits for a result. This form From 5ae7e54dacab53acefdffae60928e9a48e4472f0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 12 Sep 2015 16:24:52 -0600 Subject: [PATCH 217/381] {eval,compile,expand}-syntax: install top-level fallback less often Make `eval-syntax`, `compile-syntax`, and `expand-syntax` more consistent (with intent and each other) by not installing a fallback automatically. In particular, a fallback is not installed for a `module` form, so that different ways of expanding a `module` form produce consistent results (e.g., for ambiguous bindings). --- .../racket-test-core/tests/racket/module.rktl | 19 +++++++ racket/src/racket/src/compenv.c | 5 +- racket/src/racket/src/eval.c | 57 +++++++------------ 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 1219adc878..1d292d43bc 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1554,6 +1554,25 @@ case of module-leve bindings; it doesn't cover local bindings. (begin-for-syntax (begin-for-syntax))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure `eval-syntax` doesn't create a fallback context + +(module exports-cons-with-context racket/base + (provide cons-id) + (define cons-id #'cons)) +(require 'exports-cons-with-context racket/base) + +(let ([mod (datum->syntax #f `(,#'module m racket/base + ;; If a fallback is installed, then + ;; the module context of `cons` applies: + ,cons-id))]) + (err/rt-test (eval-syntax mod) + (lambda (exn) (regexp-match #rx"ambiguous" (exn-message exn))))) + +;; `eval` should install a fallback for a non`-module` form: +(test (void) eval (datum->syntax #f `(begin (,#'module m racket/base + ,cons-id)))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index b38bd15f7a..c718f3ad9e 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -1204,9 +1204,8 @@ scheme_compile_lookup(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, NULL, NULL, NULL, NULL); #if 0 - // REMOVEME - if (!strcmp("define$", SCHEME_SYM_VAL(SCHEME_STX_VAL(find_id)))) { - printf("%p\n", find_id); + if (!strcmp("cons", SCHEME_SYM_VAL(SCHEME_STX_VAL(find_id)))) { + printf("%s\n", scheme_write_to_string(find_id, 0)); scheme_stx_debug_print(find_id, scheme_env_phase(env->genv), 1); printf("%s\n", scheme_write_to_string(binding, NULL)); } diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 879e6745ed..518331074b 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -4096,7 +4096,7 @@ static void *compile_k(void) { Scheme_Thread *p = scheme_current_thread; Scheme_Object *form, *frame_scopes; - int writeable, for_eval, rename, enforce_consts, comp_flags; + int writeable, for_eval, top_intro, enforce_consts, comp_flags; Scheme_Env *genv; Scheme_Compile_Info rec, rec2; Scheme_Object *o, *rl, *tl_queue; @@ -4104,32 +4104,26 @@ static void *compile_k(void) Resolve_Prefix *rp; Resolve_Info *ri; Optimize_Info *oi; - Scheme_Object *gval, *insp, *rib; + Scheme_Object *gval, *insp; Scheme_Comp_Env *cenv; form = (Scheme_Object *)p->ku.k.p1; genv = (Scheme_Env *)p->ku.k.p2; writeable = p->ku.k.i1; for_eval = p->ku.k.i2; - rename = p->ku.k.i3; + top_intro = p->ku.k.i3; p->ku.k.p1 = NULL; p->ku.k.p2 = NULL; if (!SCHEME_STXP(form)) { form = scheme_datum_to_syntax(form, scheme_false, scheme_false, 1, 0); - rename = 1; + top_intro = 1; } - /* Renamings for requires: */ - if (rename) + if (top_intro) form = scheme_top_introduce(form, genv); - if (for_eval) - rib = genv->stx_context; - else - rib = NULL; - tl_queue = scheme_null; { @@ -4149,12 +4143,6 @@ static void *compile_k(void) else frame_scopes = NULL; - if (for_eval) { - /* For the top-level environment, we "push_introduce" instead of "introduce" - to avoid ambiguous bindings. */ - form = scheme_stx_push_introduce_module_context(form, genv->stx_context); - } - while (1) { scheme_prepare_compile_env(genv); @@ -4174,10 +4162,8 @@ static void *compile_k(void) | SCHEME_TMP_TL_BIND_FRAME); create_binding_namess(cenv); - if (rib) { - cenv->expand_result_adjust = scheme_stx_push_introduce_module_context; - cenv->expand_result_adjust_arg = rib; - } + cenv->expand_result_adjust = scheme_stx_push_introduce_module_context; + cenv->expand_result_adjust_arg = genv->stx_context; if (for_eval) { /* Need to look for top-level `begin', and if we @@ -4194,7 +4180,6 @@ static void *compile_k(void) 1); if (SAME_OBJ(gval, scheme_begin_syntax)) { if (scheme_stx_proper_list_length(form) > 1) { - form = scheme_stx_push_introduce_module_context(form, genv->stx_context); form = SCHEME_STX_CDR(form); tl_queue = scheme_append(scheme_flatten_syntax_list(form, NULL), tl_queue); @@ -4216,8 +4201,7 @@ static void *compile_k(void) tl_queue = scheme_append(rl, tl_queue); form = SCHEME_CAR(tl_queue); tl_queue = SCHEME_CDR(tl_queue); - } else - form = scheme_stx_push_introduce_module_context(form, genv->stx_context); + } break; } } @@ -4332,7 +4316,7 @@ static void *compile_k(void) return (void *)top; } -static Scheme_Object *_compile(Scheme_Object *form, Scheme_Env *env, int writeable, int for_eval, int eb, int rename) +static Scheme_Object *_compile(Scheme_Object *form, Scheme_Env *env, int writeable, int for_eval, int eb, int top_intro) { Scheme_Thread *p = scheme_current_thread; @@ -4348,7 +4332,7 @@ static Scheme_Object *_compile(Scheme_Object *form, Scheme_Env *env, int writeab p->ku.k.p2 = env; p->ku.k.i1 = writeable; p->ku.k.i2 = for_eval; - p->ku.k.i3 = rename; + p->ku.k.i3 = top_intro; return (Scheme_Object *)scheme_top_level_do(compile_k, eb); } @@ -4636,12 +4620,12 @@ static void *expand_k(void) Scheme_Object *obj, *observer, *catch_lifts_key; Scheme_Comp_Env *env, **ip; Scheme_Expand_Info erec1; - int depth, rename, just_to_top, as_local, comp_flags; + int depth, top_intro, just_to_top, as_local, comp_flags; obj = (Scheme_Object *)p->ku.k.p1; env = (Scheme_Comp_Env *)p->ku.k.p2; depth = p->ku.k.i1; - rename = p->ku.k.i2; + top_intro = p->ku.k.i2; just_to_top = p->ku.k.i3; catch_lifts_key = p->ku.k.p4; as_local = p->ku.k.i4; /* < 0 => catch lifts to let */ @@ -4657,13 +4641,10 @@ static void *expand_k(void) if (!SCHEME_STXP(obj)) obj = scheme_datum_to_syntax(obj, scheme_false, scheme_false, 1, 0); - if (rename > 0) { - /* Renamings for requires: */ + if (top_intro) obj = scheme_top_introduce(obj, env->genv); - } - if (rename && env->genv->stx_context) { - obj = scheme_stx_push_introduce_module_context(obj, env->genv->stx_context); + if (!as_local) { env->expand_result_adjust = scheme_stx_push_introduce_module_context; env->expand_result_adjust_arg = env->genv->stx_context; } @@ -4746,7 +4727,7 @@ static void *expand_k(void) } static Scheme_Object *r_expand(Scheme_Object *obj, Scheme_Comp_Env *env, - int depth, int rename, int just_to_top, + int depth, int top_intro, int just_to_top, Scheme_Object *catch_lifts_key, int eb, int as_local) /* as_local < 0 => catch lifts to let; @@ -4757,7 +4738,7 @@ static Scheme_Object *r_expand(Scheme_Object *obj, Scheme_Comp_Env *env, p->ku.k.p1 = obj; p->ku.k.p2 = env; p->ku.k.i1 = depth; - p->ku.k.i2 = rename; + p->ku.k.i2 = top_intro; p->ku.k.i3 = just_to_top; p->ku.k.p4 = catch_lifts_key; p->ku.k.i4 = as_local; @@ -4995,7 +4976,7 @@ static Scheme_Object *expand_stx(int argc, Scheme_Object **argv) return r_expand(argv[0], scheme_new_expand_env(env, NULL, scheme_true, SCHEME_TOPLEVEL_FRAME | SCHEME_KEEP_SCOPES_FRAME), - -1, -1, 0, scheme_false, 0, 0); + -1, 0, 0, scheme_false, 0, 0); } int scheme_is_expansion_context_symbol(Scheme_Object *v) @@ -5489,7 +5470,7 @@ expand_stx_once(int argc, Scheme_Object **argv) return r_expand(argv[0], scheme_new_expand_env(env, NULL, scheme_true, SCHEME_TOPLEVEL_FRAME | SCHEME_KEEP_SCOPES_FRAME), - 1, -1, 0, scheme_false, 0, 0); + 1, 0, 0, scheme_false, 0, 0); } static Scheme_Object * @@ -5518,7 +5499,7 @@ expand_stx_to_top_form(int argc, Scheme_Object **argv) return r_expand(argv[0], scheme_new_expand_env(env, NULL, scheme_true, SCHEME_TOPLEVEL_FRAME | SCHEME_KEEP_SCOPES_FRAME), - 1, -1, 1, scheme_false, 0, 0); + 1, 0, 1, scheme_false, 0, 0); } static Scheme_Object *do_eval_string_all(Scheme_Object *port, const char *str, Scheme_Env *env, From ab2aaff6bea55662af0547269c6c0bc417ec964a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 13 Sep 2015 08:24:27 -0600 Subject: [PATCH 218/381] optimizer: fix `let-values` splitting and allocation reordering First bug: When the optimize converts (let-values ([(X ...) (values M ...)]) ....) to (let ([X M] ...) ....) it incorrectly attached a virtual timestamp to each "[X M]" binding that corresponds to the timestamp after the whole `(values M ...)`. The solution is to approximate tracking the timestamp for invidual expressions. Second bug: The compiler could reorder a continuation-capturing expression past an allocation. The solution is to track allocations with a new virtual clock. --- .../tests/racket/optimize.rktl | 43 ++- racket/src/racket/src/letrec_check.c | 2 +- racket/src/racket/src/list.c | 14 +- racket/src/racket/src/optimize.c | 266 +++++++++++++++--- racket/src/racket/src/schpriv.h | 33 ++- racket/src/racket/src/vector.c | 4 +- 6 files changed, 298 insertions(+), 64 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 3e0b06e36f..c4a1ac3674 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -2004,19 +2004,52 @@ (test '((1) (2)) f (lambda (n) (set! v n) n)) (test 2 values v))) +;; Make sure `values` splitting doesn't use wrong clock values +;; leading to reordering: +(test-comp '(lambda (p) + (define-values (x y) (values (car p) (cdr p))) + (values y x)) + '(lambda (p) + (values (#%unsafe-cdr p) (car p))) + #f) +(test-comp '(lambda (p) + (define-values (x y) (values (car p) (cdr p))) + (values y x)) + '(lambda (p) + (let ([x (car p)]) + (values (unsafe-cdr p) x)))) + (test-comp '(lambda (z) - ;; Moving `(list z)` before `(list (z 2))` - ;; would reorder, which is not allowed, so check - ;; that the optimizer can keep track: + ;; Moving `(list z)` after `(list (z 2))` is not allowed + ;; in case `(z 2)` captures a continuation: (let-values ([(a b) (values (list z) (list (z 2)))]) - (list a b))) + (list b a))) '(lambda (z) - (list (list z) (list (z 2))))) + (list (list (z 2)) (list z))) + #f) +(test-comp '(lambda (z) + (let-values ([(a b) (values (list (z 2)) (list z))]) + (list a a b))) + '(lambda (z) + (let ([a (list (z 2))]) + (list a a (list z))))) + +;; It would be nice if the optimizer could do these two, but because it +;; involves temporarily reordering `(list z)` and `(list (z 2))` +;; (which is not allowed in case `(z 2)` captures a continuation), +;; the optimizer currently cannot manage it: +#; (test-comp '(lambda (z) (let-values ([(a b) (values (list (z 2)) (list z))]) (list a b))) '(lambda (z) (list (list (z 2)) (list z)))) +#; +(test-comp '(lambda (z) + (let-values ([(a b) (values (list z) (list (z 2)))]) + (list a b))) + '(lambda (z) + (list (list z) (list (z 2))))) (test-comp '(module m racket/base ;; Reference to a ready module-level variable shouldn't diff --git a/racket/src/racket/src/letrec_check.c b/racket/src/racket/src/letrec_check.c index 74c84f2317..f112f33a92 100644 --- a/racket/src/racket/src/letrec_check.c +++ b/racket/src/racket/src/letrec_check.c @@ -457,7 +457,7 @@ static Scheme_Object *letrec_check_local(Scheme_Object *o, Letrec_Check_Frame *f static int is_effect_free_prim(Scheme_Object *rator) { if (SCHEME_PRIMP(rator) - && (SCHEME_PRIM_PROC_OPT_FLAGS(rator) & SCHEME_PRIM_IS_OMITABLE)) + && (SCHEME_PRIM_PROC_OPT_FLAGS(rator) & SCHEME_PRIM_IS_OMITABLE_ANY)) return 1; return 0; diff --git a/racket/src/racket/src/list.c b/racket/src/racket/src/list.c index ded6ceac34..60a99888e2 100644 --- a/racket/src/racket/src/list.c +++ b/racket/src/racket/src/list.c @@ -209,7 +209,7 @@ scheme_init_list (Scheme_Env *env) p = scheme_make_immed_prim(cons_prim, "cons", 2, 2); scheme_cons_proc = p; SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant ("cons", p, env); p = scheme_make_folding_prim(scheme_checked_car, "car", 1, 1, 1); @@ -224,7 +224,7 @@ scheme_init_list (Scheme_Env *env) p = scheme_make_immed_prim(mcons_prim, "mcons", 2, 2); scheme_mcons_proc = p; SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant ("mcons", p, env); p = scheme_make_immed_prim(scheme_checked_mcar, "mcar", 1, 1); @@ -263,7 +263,7 @@ scheme_init_list (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED | SCHEME_PRIM_IS_BINARY_INLINED | SCHEME_PRIM_IS_NARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant ("list", p, env); REGISTER_SO(scheme_list_star_proc); @@ -272,7 +272,7 @@ scheme_init_list (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED | SCHEME_PRIM_IS_BINARY_INLINED | SCHEME_PRIM_IS_NARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant ("list*", p, env); p = scheme_make_folding_prim(immutablep, "immutable?", 1, 1, 1); @@ -434,13 +434,13 @@ scheme_init_list (Scheme_Env *env) p = scheme_make_immed_prim(box, BOX, 1, 1); scheme_box_proc = p; SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant(BOX, p, env); REGISTER_SO(scheme_box_immutable_proc); p = scheme_make_immed_prim(immutable_box, "box-immutable", 1, 1); scheme_box_immutable_proc = p; - SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_OMITABLE); + SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant("box-immutable", p, env); REGISTER_SO(scheme_box_p_proc); @@ -765,7 +765,7 @@ scheme_init_unsafe_list (Scheme_Env *env) REGISTER_SO(scheme_unsafe_cons_list_proc); p = scheme_make_immed_prim(unsafe_cons_list, "unsafe-cons-list", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant ("unsafe-cons-list", p, env); scheme_unsafe_cons_list_proc = p; diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 51b90cbca0..d8f6293cb4 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -57,18 +57,26 @@ struct Optimize_Info /* Propagated up and down the chain: */ int size; - int vclock; /* virtual clock that ticks for a side effect or branch; + int vclock; /* virtual clock that ticks for a side effect, a branch, + or a dependency on an earlier side-effect (such as a + previous guard on an unsafe operation's argument); the clock is only compared between binding sites and uses, so we can rewind the clock at a join after an increment that models a branch (if the branch is not taken or doesn't increment the clock) */ - int kclock; /* virtual clock that ticks for a potential continuation capture */ + int aclock; /* virtual clock that ticks for allocation without side effects, + for constraining the reordering of operations that might + capture a continuation */ + int kclock; /* virtual clock that ticks for a potential continuation capture, + for constraining the movement of allocation operations */ int sclock; /* virtual clock that ticks when space consumption is potentially observed */ int psize; short inline_fuel, shift_fuel; char letrec_not_twice, enforce_const, use_psize, has_nonleaf; Scheme_Hash_Table *top_level_consts; + int maybe_values_argument; /* triggers an approximation for clock increments */ + /* Set by expression optimization: */ int single_result, preserves_marks; /* negative means "tentative", due to fixpoint in progress */ int escapes; /* flag to signal that the expression allways escapes. When escapes is 1, it's assumed @@ -174,8 +182,10 @@ typedef struct Scheme_Once_Used { Scheme_Object *expr; int pos; int vclock; + int aclock; int kclock; int sclock; + int spans_k; /* potentially captures a continuation */ int used; int delta; @@ -186,7 +196,7 @@ typedef struct Scheme_Once_Used { } Scheme_Once_Used; static Scheme_Once_Used *make_once_used(Scheme_Object *val, int pos, - int vclock, int kclock, int sclock, + int vclock, int aclock, int kclock, int sclock, int spans_k, Scheme_Once_Used *prev); #ifdef MZ_PRECISE_GC @@ -208,7 +218,7 @@ int scheme_is_functional_nonfailing_primitive(Scheme_Object *rator, int num_args /* return 2 => results are a constant when arguments are constants */ { if (SCHEME_PRIMP(rator) - && (SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_OMITABLE | SCHEME_PRIM_IS_UNSAFE_NONMUTATING)) + && (SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_OMITABLE_ANY | SCHEME_PRIM_IS_UNSAFE_NONMUTATING)) && (num_args >= ((Scheme_Primitive_Proc *)rator)->mina) && (num_args <= ((Scheme_Primitive_Proc *)rator)->mu.maxa) && ((expected_vals < 0) @@ -2236,10 +2246,13 @@ static Scheme_Object *check_app_let_rator(Scheme_Object *app, Scheme_Object *rat return scheme_optimize_expr(orig_rator, info, context); } -static int is_nonmutating_primitive(Scheme_Object *rator, int n) +static int is_nonmutating_nondependant_primitive(Scheme_Object *rator, int n) +/* Does not include SCHEME_PRIM_IS_UNSAFE_OMITABLE, because those can + depend on earlier tests (explicit or implicit) for whether the + unsafe operation is defined */ { if (SCHEME_PRIMP(rator) - && (SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_OMITABLE)) + && (SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_OMITABLE | SCHEME_PRIM_IS_OMITABLE_ALLOCATION)) && (n >= ((Scheme_Primitive_Proc *)rator)->mina) && (n <= ((Scheme_Primitive_Proc *)rator)->mu.maxa)) return 1; @@ -2247,6 +2260,14 @@ static int is_nonmutating_primitive(Scheme_Object *rator, int n) return 0; } +static int is_primitive_allocating(Scheme_Object *rator, int n) +{ + if (SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_OMITABLE_ALLOCATION)) + return 1; + + return 0; +} + static int is_noncapturing_primitive(Scheme_Object *rator, int n) { if (SCHEME_PRIMP(rator)) { @@ -2781,6 +2802,9 @@ static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info le = optimize_for_inline(info, app->args[i], n - 1, app, NULL, NULL, &rator_flags, context, 1, 0); if (le) return le; + if (SAME_TYPE(app->args[0], scheme_values_func) + || SAME_TYPE(app->args[0], scheme_apply_proc)) + info->maybe_values_argument = 1; rator_apply_escapes = info->escapes; } } @@ -2921,6 +2945,44 @@ static Scheme_Object *finish_optimize_any_application(Scheme_Object *app, Scheme return app; } +static void increment_clock_counts_for_application(GC_CAN_IGNORE int *_vclock, + GC_CAN_IGNORE int *_aclock, + GC_CAN_IGNORE int *_kclock, + GC_CAN_IGNORE int *_sclock, + Scheme_Object *rator, + int argc) +{ + if (!is_nonmutating_nondependant_primitive(rator, argc)) + *_vclock += 1; + else if (is_primitive_allocating(rator, argc)) + *_aclock += 1; + + if (!is_noncapturing_primitive(rator, argc)) + *_kclock += 1; + + if (!is_nonsaving_primitive(rator, argc)) + *_sclock += 1; +} + +static void increment_clocks_for_application(Optimize_Info *info, + Scheme_Object *rator, + int argc) +{ + int v, a, k, s; + + v = info->vclock; + a = info->aclock; + k = info->kclock; + s = info->sclock; + + increment_clock_counts_for_application(&v, &a, &k, &s, rator, argc); + + info->vclock = v; + info->aclock = a; + info->kclock = k; + info->sclock = s; +} + static Scheme_Object *finish_optimize_application(Scheme_App_Rec *app, Optimize_Info *info, int context, int rator_flags) { Scheme_Object *le; @@ -2932,13 +2994,8 @@ static Scheme_Object *finish_optimize_application(Scheme_App_Rec *app, Optimize_ } info->size += 1; - if (!is_nonmutating_primitive(app->args[0], app->num_args)) - info->vclock += 1; - if (!is_noncapturing_primitive(app->args[0], app->num_args)) - info->kclock += 1; - if (!is_nonsaving_primitive(app->args[0], app->num_args)) - info->sclock += 1; - + increment_clocks_for_application(info, app->args[0], app->num_args); + if (all_vals) { le = try_optimize_fold(app->args[0], NULL, (Scheme_Object *)app, info); if (le) @@ -3214,12 +3271,7 @@ static Scheme_Object *finish_optimize_application2(Scheme_App2_Rec *app, Optimiz return replace_tail_inside(le, inside, app->rand); } - if (!is_nonmutating_primitive(rator, 1)) - info->vclock += 1; - if (!is_noncapturing_primitive(rator, 1)) - info->kclock += 1; - if (!is_nonsaving_primitive(rator, 1)) - info->sclock += 1; + increment_clocks_for_application(info, rator, 1); info->preserves_marks = !!(rator_flags & CLOS_PRESERVES_MARKS); info->single_result = !!(rator_flags & CLOS_SINGLE_RESULT); @@ -3476,6 +3528,10 @@ static Scheme_Object *optimize_application3(Scheme_Object *o, Optimize_Info *inf rator_apply_escapes = info->escapes; } + if (SAME_TYPE(app->rator, scheme_values_func) + || SAME_TYPE(app->rator, scheme_apply_proc)) + info->maybe_values_argument = 1; + /* 1st arg */ ty = wants_local_type_arguments(app->rator, 0); @@ -3548,12 +3604,7 @@ static Scheme_Object *finish_optimize_application3(Scheme_App3_Rec *app, Optimiz return le; } - if (!is_nonmutating_primitive(app->rator, 2)) - info->vclock += 1; - if (!is_noncapturing_primitive(app->rator, 2)) - info->kclock += 1; - if (!is_nonsaving_primitive(app->rator, 2)) - info->sclock += 1; + increment_clocks_for_application(info, app->rator, 2); /* Check for (call-with-values (lambda () M) N): */ if (SAME_OBJ(app->rator, scheme_call_with_values_proc)) { @@ -4218,9 +4269,9 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int Scheme_Branch_Rec *b; Scheme_Object *t, *tb, *fb; Scheme_Hash_Tree *init_types, *then_types; - int init_vclock, init_kclock, init_sclock; + int init_vclock, init_aclock, init_kclock, init_sclock; int then_escapes, then_preserves_marks, then_single_result; - int then_vclock, then_kclock, then_sclock; + int then_vclock, then_aclock, then_kclock, then_sclock; Optimize_Info_Sequence info_seq; Scheme_Object *pred; @@ -4333,6 +4384,7 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int info->vclock += 1; /* model branch as clock increment */ init_vclock = info->vclock; + init_aclock = info->aclock; init_kclock = info->kclock; init_sclock = info->sclock; init_types = info->types; @@ -4346,11 +4398,13 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int then_single_result = info->single_result; then_escapes = info->escapes; then_vclock = info->vclock; + then_aclock = info->aclock; then_kclock = info->kclock; then_sclock = info->sclock; info->types = init_types; info->vclock = init_vclock; + info->aclock = init_aclock; info->kclock = init_kclock; info->sclock = init_sclock; @@ -4390,6 +4444,8 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int if (then_sclock > info->sclock) info->sclock = then_sclock; + if (then_aclock > info->aclock) + info->aclock = then_aclock; if ((init_vclock == then_vclock) && (init_vclock == info->vclock)) { /* we can rewind the vclock to just after the test, because the @@ -5644,6 +5700,74 @@ int scheme_might_invoke_call_cc(Scheme_Object *value) return !scheme_is_liftable(value, -1, 10, 0, 1); } +#define ADVANCE_CLOCKS_INIT_FUEL 3 + +void advance_clocks_for_optimized(Scheme_Object *o, + GC_CAN_IGNORE int *_vclock, + GC_CAN_IGNORE int *_aclock, + GC_CAN_IGNORE int *_kclock, + GC_CAN_IGNORE int *_sclock, + Optimize_Info *info, + int fuel) +/* It's ok for this function to advance clocks *less* than + acurrately, but not more than acurrately */ +{ + Scheme_Object *rator = NULL; + int argc = 0; + + if (!fuel) return; + + switch (SCHEME_TYPE(o)) { + case scheme_application_type: + { + Scheme_App_Rec *app = (Scheme_App_Rec *)o; + int i; + for (i = 0; i < app->num_args; i++) { + advance_clocks_for_optimized(app->args[i+1], + _vclock, _aclock, _kclock, _sclock, + info, fuel - 1); + } + rator = app->args[0]; + argc = app->num_args; + } + break; + case scheme_application2_type: + { + Scheme_App2_Rec *app = (Scheme_App2_Rec *)o; + advance_clocks_for_optimized(app->rand, + _vclock, _aclock, _kclock, _sclock, + info, fuel - 1); + rator = app->rator; + argc = 1; + break; + } + case scheme_application3_type: + { + Scheme_App3_Rec *app = (Scheme_App3_Rec *)o; + advance_clocks_for_optimized(app->rand1, + _vclock, _aclock, _kclock, _sclock, + info, fuel - 1); + advance_clocks_for_optimized(app->rand2, + _vclock, _aclock, _kclock, _sclock, + info, fuel - 1); + rator = app->rator; + argc = 2; + } + break; + default: + break; + } + + if (rator) + increment_clock_counts_for_application(_vclock, _aclock, _kclock, _sclock, rator, argc); + + if ((*_vclock > info->vclock) + || (*_aclock > info->aclock) + || (*_kclock > info->kclock) + || (*_sclock > info->sclock)) + scheme_signal_error("internal error: optimizer clock tracking has gone wrong"); +} + static int worth_lifting(Scheme_Object *v) { Scheme_Type lhs; @@ -5671,6 +5795,8 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i int did_set_value, checked_once, skip_depth, unused_clauses, found_escapes; int remove_last_one = 0, inline_fuel, rev_bind_order; int post_bind = !(SCHEME_LET_FLAGS(head) & (SCHEME_LET_RECURSIVE | SCHEME_LET_STAR)); + int pre_vclock, pre_aclock, pre_kclock, pre_sclock, increments_kclock; + int once_vclock, once_aclock, once_kclock, once_sclock, once_increments_kclock; # define pos_EARLIER(a, b) (rev_bind_order ? ((a) > (b)) : ((a) < (b))) @@ -5958,6 +6084,10 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i } if (!skip_opts) { + pre_vclock = rhs_info->vclock; + pre_aclock = rhs_info->aclock; + pre_kclock = rhs_info->kclock; + pre_sclock = rhs_info->sclock; if (!found_escapes) { optimize_info_seq_step(rhs_info, &info_seq); value = scheme_optimize_expr(pre_body->value, rhs_info, @@ -5976,9 +6106,41 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i body_info->escapes = 1; body_info->size++; } + once_vclock = rhs_info->vclock; + once_aclock = rhs_info->aclock; + once_kclock = rhs_info->kclock; + once_sclock = rhs_info->sclock; + increments_kclock = (once_kclock > pre_kclock); + once_increments_kclock = increments_kclock; } else { value = pre_body->value; --skip_opts; + if (skip_opts) { + /* when a `values` group is split, we've lost track of the + clock values for points between the `values` arguments; + we can conservatively assume the clock before the whole group + for the purpose of registering once-used variables, + but we can also conservatively advance the clock: */ + advance_clocks_for_optimized(value, + &pre_vclock, &pre_aclock, &pre_kclock, &pre_sclock, + rhs_info, + ADVANCE_CLOCKS_INIT_FUEL); + once_vclock = pre_vclock; + once_aclock = pre_aclock; + once_kclock = pre_kclock; + once_sclock = pre_sclock; + } else { + /* end of split group, so rhs_info clock is right */ + once_vclock = rhs_info->vclock; + once_aclock = rhs_info->aclock; + once_kclock = rhs_info->kclock; + once_sclock = rhs_info->sclock; + } + if (increments_kclock) { + /* note that we conservatively assume that a member of a split + advance the kclock, unless we can easily show otherwise */ + once_increments_kclock = 1; + } } if (undiscourage) { @@ -6030,7 +6192,7 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i int *new_flags; int cnt; - /* This conversion may reorder the expressions. */ + /* This conversion reorders the expressions if rev_bind_order. */ if (pre_body->count) { if (rev_bind_order) cnt = 0; @@ -6089,6 +6251,18 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i body = (Scheme_Object *)naya; value = pre_body->value; pos = pre_body->position; + + if (skip_opts) { + /* Use "pre" clocks: */ + advance_clocks_for_optimized(value, + &pre_vclock, &pre_aclock, &pre_kclock, &pre_sclock, + rhs_info, + ADVANCE_CLOCKS_INIT_FUEL); + once_vclock = pre_vclock; + once_aclock = pre_aclock; + once_kclock = pre_kclock; + once_sclock = pre_sclock; + } } else { /* We've dropped this clause entirely. */ i++; @@ -6193,7 +6367,8 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i /* used only once; we may be able to shift the expression to the use site, instead of binding to a temporary */ once_used = make_once_used(value, pos, - rhs_info->vclock, rhs_info->kclock, rhs_info->sclock, + once_vclock, once_aclock, once_kclock, once_sclock, + once_increments_kclock, NULL); if (!last_once_used) first_once_used = once_used; @@ -6215,7 +6390,8 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i if (cnt == 1) { /* Need to register as once-used, in case of copy propagation */ once_used = make_once_used(NULL, pos+i, - rhs_info->vclock, rhs_info->kclock, rhs_info->sclock, + once_vclock, once_aclock, once_kclock, once_sclock, + once_increments_kclock, NULL); if (!last_once_used) first_once_used = once_used; @@ -6424,6 +6600,7 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i info->single_result = body_info->single_result; info->preserves_marks = body_info->preserves_marks; info->vclock = body_info->vclock; + info->aclock = body_info->aclock; info->kclock = body_info->kclock; info->sclock = body_info->sclock; @@ -6593,7 +6770,7 @@ optimize_closure_compilation(Scheme_Object *_data, Optimize_Info *info, int cont Scheme_Object *code, *ctx; Closure_Info *cl; mzshort dcs, *dcm; - int i, cnt, init_vclock, init_kclock, init_sclock; + int i, cnt, init_vclock, init_aclock, init_kclock, init_sclock; Scheme_Once_Used *first_once_used = NULL, *last_once_used = NULL; data = (Scheme_Closure_Data *)_data; @@ -6605,6 +6782,7 @@ optimize_closure_compilation(Scheme_Object *_data, Optimize_Info *info, int cont SCHEME_LAMBDA_FRAME); init_vclock = info->vclock; + init_aclock = info->aclock; init_kclock = info->kclock; init_sclock = info->sclock; @@ -6630,7 +6808,7 @@ optimize_closure_compilation(Scheme_Object *_data, Optimize_Info *info, int cont cnt = ((cl->local_flags[i] & SCHEME_USE_COUNT_MASK) >> SCHEME_USE_COUNT_SHIFT); if (cnt == 1) { last_once_used = make_once_used(NULL, i, - info->vclock, info->kclock, info->sclock, + info->vclock, info->aclock, info->kclock, info->sclock, 0, last_once_used); if (!first_once_used) first_once_used = last_once_used; optimize_propagate(info, i, (Scheme_Object *)last_once_used, 1); @@ -6684,6 +6862,7 @@ optimize_closure_compilation(Scheme_Object *_data, Optimize_Info *info, int cont /* closure itself is not an effect */ info->vclock = init_vclock; + info->aclock = init_aclock; info->kclock = init_kclock; info->sclock = init_sclock; info->escapes = 0; @@ -7608,6 +7787,8 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info, in if (SAME_TYPE(SCHEME_TYPE(val), scheme_once_used_type)) { Scheme_Once_Used *o = (Scheme_Once_Used *)val; if (((o->vclock == info->vclock) + && ((o->aclock == info->aclock) + || !o->spans_k) && ((context & OPT_CONTEXT_SINGLED) || single_valued_noncm_expression(o->expr, 5))) || movable_expression(o->expr, info, o->delta, o->cross_lambda, @@ -7617,20 +7798,32 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info, in val = optimize_clone(1, o->expr, info, o->delta, 0); if (val) { int save_fuel = info->inline_fuel, save_no_types = info->no_types; - int save_vclock, save_kclock, save_sclock; + int save_vclock, save_aclock, save_kclock, save_sclock; info->size -= 1; o->used = 1; info->inline_fuel = 0; /* no more inlining; o->expr was already optimized */ info->no_types = 1; /* cannot used inferred types, in case `val' inferred them */ save_vclock = info->vclock; /* allowed to move => no change to clocks */ + save_aclock = info->aclock; save_kclock = info->kclock; save_sclock = info->sclock; val = scheme_optimize_expr(val, info, context); + if (info->maybe_values_argument) { + /* Although `val` could be counted as taking 0 time, we advance + the clock conservatively to be consistent with `values` + splitting. */ + advance_clocks_for_optimized(val, + &save_vclock, &save_aclock, &save_kclock, &save_sclock, + info, + ADVANCE_CLOCKS_INIT_FUEL); + } + info->inline_fuel = save_fuel; info->no_types = save_no_types; info->vclock = save_vclock; + info->aclock = save_aclock; info->kclock = save_kclock; info->sclock = save_sclock; return val; @@ -8468,7 +8661,7 @@ static void optimize_propagate(Optimize_Info *info, int pos, Scheme_Object *valu } static Scheme_Once_Used *make_once_used(Scheme_Object *val, int pos, - int vclock, int kclock, int sclock, + int vclock, int aclock, int kclock, int sclock, int spans_k, Scheme_Once_Used *prev) { Scheme_Once_Used *o; @@ -8479,8 +8672,10 @@ static Scheme_Once_Used *make_once_used(Scheme_Object *val, int pos, o->expr = val; o->pos = pos; o->vclock = vclock; + o->aclock = aclock; o->kclock = kclock; o->sclock = sclock; + o->spans_k = spans_k; if (prev) prev->next = o; @@ -8853,10 +9048,12 @@ static Optimize_Info *optimize_info_add_frame(Optimize_Info *info, int orig, int naya->top_level_consts = info->top_level_consts; naya->context = info->context; naya->vclock = info->vclock; + naya->aclock = info->aclock; naya->kclock = info->kclock; naya->sclock = info->sclock; naya->escapes = info->escapes; naya->init_kclock = info->kclock; + naya->maybe_values_argument = info->maybe_values_argument; naya->use_psize = info->use_psize; naya->logger = info->logger; naya->no_types = info->no_types; @@ -8888,6 +9085,7 @@ static void optimize_info_done(Optimize_Info *info, Optimize_Info *parent) parent->size += info->size; parent->vclock = info->vclock; + parent->aclock = info->aclock; parent->kclock = info->kclock; parent->sclock = info->sclock; parent->escapes = info->escapes; diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index ee7d129c48..6bda377bfa 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -61,25 +61,28 @@ /* We support 2^SCHEME_PRIM_OPT_INDEX_SIZE combinations of optimization flags: */ -#define SCHEME_PRIM_IS_UNARY_INLINED 1 -#define SCHEME_PRIM_IS_BINARY_INLINED 2 -#define SCHEME_PRIM_IS_NARY_INLINED 4 -#define SCHEME_PRIM_IS_UNSAFE_OMITABLE 8 -#define SCHEME_PRIM_IS_OMITABLE 16 -#define SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL 32 -#define SCHEME_PRIM_WANTS_FLONUM_FIRST 64 -#define SCHEME_PRIM_WANTS_FLONUM_SECOND 128 -#define SCHEME_PRIM_WANTS_FLONUM_THIRD 256 -#define SCHEME_PRIM_WANTS_EXTFLONUM_FIRST 512 -#define SCHEME_PRIM_WANTS_EXTFLONUM_SECOND 1024 -#define SCHEME_PRIM_WANTS_EXTFLONUM_THIRD 2048 -#define SCHEME_PRIM_IS_UNSAFE_NONALLOCATE 4096 -#define SCHEME_PRIM_ALWAYS_ESCAPES 8192 +#define SCHEME_PRIM_IS_UNARY_INLINED (1 << 0) +#define SCHEME_PRIM_IS_BINARY_INLINED (1 << 1) +#define SCHEME_PRIM_IS_NARY_INLINED (1 << 2) +#define SCHEME_PRIM_IS_UNSAFE_OMITABLE (1 << 3) +#define SCHEME_PRIM_IS_OMITABLE (1 << 4) +#define SCHEME_PRIM_IS_OMITABLE_ALLOCATION (1 << 5) +#define SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL (1 << 6) +#define SCHEME_PRIM_WANTS_FLONUM_FIRST (1 << 7) +#define SCHEME_PRIM_WANTS_FLONUM_SECOND (1 << 8) +#define SCHEME_PRIM_WANTS_FLONUM_THIRD (1 << 9) +#define SCHEME_PRIM_WANTS_EXTFLONUM_FIRST (1 << 10) +#define SCHEME_PRIM_WANTS_EXTFLONUM_SECOND (1 << 11) +#define SCHEME_PRIM_WANTS_EXTFLONUM_THIRD (1 << 12) +#define SCHEME_PRIM_IS_UNSAFE_NONALLOCATE (1 << 13) +#define SCHEME_PRIM_ALWAYS_ESCAPES (1 << 14) -#define SCHEME_PRIM_OPT_TYPE_SHIFT 14 +#define SCHEME_PRIM_OPT_TYPE_SHIFT 15 #define SCHEME_PRIM_OPT_TYPE_MASK (SCHEME_MAX_LOCAL_TYPE_MASK << SCHEME_PRIM_OPT_TYPE_SHIFT) #define SCHEME_PRIM_OPT_TYPE(x) ((x & SCHEME_PRIM_OPT_TYPE_MASK) >> SCHEME_PRIM_OPT_TYPE_SHIFT) +#define SCHEME_PRIM_IS_OMITABLE_ANY (SCHEME_PRIM_IS_OMITABLE | SCHEME_PRIM_IS_OMITABLE_ALLOCATION | SCHEME_PRIM_IS_UNSAFE_OMITABLE) + #define SCHEME_PRIM_PRODUCES_FLONUM (SCHEME_LOCAL_TYPE_FLONUM << SCHEME_PRIM_OPT_TYPE_SHIFT) #define SCHEME_PRIM_PRODUCES_FIXNUM (SCHEME_LOCAL_TYPE_FIXNUM << SCHEME_PRIM_OPT_TYPE_SHIFT) diff --git a/racket/src/racket/src/vector.c b/racket/src/racket/src/vector.c index 7ff4866af0..89f742b901 100644 --- a/racket/src/racket/src/vector.c +++ b/racket/src/racket/src/vector.c @@ -91,7 +91,7 @@ scheme_init_vector (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED | SCHEME_PRIM_IS_BINARY_INLINED | SCHEME_PRIM_IS_NARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant("vector", p, env); REGISTER_SO(scheme_vector_immutable_proc); @@ -100,7 +100,7 @@ scheme_init_vector (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED | SCHEME_PRIM_IS_BINARY_INLINED | SCHEME_PRIM_IS_NARY_INLINED - | SCHEME_PRIM_IS_OMITABLE); + | SCHEME_PRIM_IS_OMITABLE_ALLOCATION); scheme_add_global_constant("vector-immutable", p, env); p = scheme_make_folding_prim(vector_length, "vector-length", 1, 1, 1); From ca64ab5e2368c2b70fe8ebfaccf6248a3c90ef81 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 13 Sep 2015 12:34:02 -0500 Subject: [PATCH 219/381] Move unstable/error to unstable-lib. --- racket/collects/unstable/error.rkt | 201 ----------------------------- 1 file changed, 201 deletions(-) delete mode 100644 racket/collects/unstable/error.rkt diff --git a/racket/collects/unstable/error.rkt b/racket/collects/unstable/error.rkt deleted file mode 100644 index 1dcd11e62e..0000000000 --- a/racket/collects/unstable/error.rkt +++ /dev/null @@ -1,201 +0,0 @@ -#lang racket/base -(require racket/contract/base - racket/string - racket/list - syntax/srcloc - syntax/stx) - -#| -TODO - - more options - - 'pretty : pretty-print, then use multi-line format as necessary - - need no-contracts version? - - document or remove #:details arg -|# - -;; A DetailsTable is (listof (cons Field any)) -;; A Field is one of -;; - string -;; - (cons string (listof FieldOption)) -;; A FieldOption is one of -;; - 'multi -;; - 'value -;; - 'maybe - -(define field-option/c (or/c 'multi 'value 'maybe)) -(define field/c (or/c string? (cons/c string? (listof field-option/c)))) - -(define details-list/c - (recursive-contract - (or/c '() (cons/c field/c (cons/c any/c details-list/c))))) - -(provide/contract - [error* - (->* [symbol? string?] - [#:continued (or/c string? (listof string))] - #:rest details-list/c - any)] - [raise-syntax-error* - (->* [string? (or/c syntax? #f) (or/c syntax? #f)] - [#:continued (or/c string? (listof string)) - #:who (or/c symbol? #f) - #:within (or/c #f syntax?)] - #:rest details-list/c - any)] - [compose-error-message - (->* [(or/c symbol? #f) string?] - [#:continued (or/c string? (listof string))] - #:rest details-list/c - string?)] - [compose-error-detail - (-> string? (listof field-option/c) any/c - string?)]) - -;; ---- - -(define (error* who message - #:continued [continued-message null] - . field+detail-list) - (raise - (exn:fail - (compose* who message - continued-message - (field+detail-list->table 'error* field+detail-list null)) - (current-continuation-marks)))) - -(define (raise-syntax-error* message0 stx sub-stx - #:who [who #f] - #:within [within-stx #f] - #:continued [continued-message null] - #:extra-sources [extra-stxs null] - . field+detail-list) - (let* ([source-stx (or stx sub-stx within-stx)] - [who (or who - (let* ([maybe-id (if (stx-pair? stx) (stx-car stx) stx)]) - (if (identifier? maybe-id) (syntax-e maybe-id) '?)))] - [message - (apply compose-error-message who message0 - #:continued continued-message - '("at" maybe) (and sub-stx - (error-print-source-location) - (format "~.s" (syntax->datum sub-stx))) - '("within" maybe) (and within-stx - (error-print-source-location) - (format "~.s" (syntax->datum within-stx))) - '("in" maybe) (and stx - (error-print-source-location) - (format "~.s" (syntax->datum stx))) - field+detail-list)] - [message - (if (error-print-source-location) - (string-append (source-location->prefix source-stx) message) - message)]) - (raise - (exn:fail:syntax message - (current-continuation-marks) - (cond [within-stx (cons within-stx extra-stxs)] - [sub-stx (cons sub-stx extra-stxs)] - [stx (cons stx extra-stxs)] - [else extra-stxs]))))) - -;; ---- - -;; compose-error-message : .... -> string -(define (compose-error-message who message - #:continued [continued-message null] - . field+detail-list) - (define details - (field+detail-list->table 'compose-error-message field+detail-list null)) - (compose* who message continued-message details)) - -;; compose-error-detail : string (listof option) any -> (listof string) -;; Note: includes a leading newline (unless detail omitted). -(define (compose-error-detail field options value) - (apply string-append (compose-detail* field options value))) - -;; ---- - -(define (compose* who message continued-message details) - (let* ([parts (apply append - (for/list ([detail (in-list details)]) - (let* ([field+opts (car detail)] - [field (if (pair? field+opts) (car field+opts) field+opts)] - [options (if (pair? field+opts) (cdr field+opts) '())] - [value (cdr detail)]) - (compose-detail* field options value))))] - [parts (let loop ([continued continued-message]) - (cond [(pair? continued) (list* "\n " (car continued) (loop (cdr continued)))] - [(string? continued) (loop (list continued))] - [(null? continued) parts]))] - [parts (list* message (if (null? continued-message) "" ";") parts)] - [parts (if who - (list* (symbol->string who) ": " parts) - parts)]) - (apply string-append parts))) - -(define (compose-detail* field options value) - (let* ([value? (memq 'value options)] - [multi? (memq 'multi options)] - [maybe? (memq 'maybe options)] - [noindent? (memq 'noindent options)] - [convert-value0 - (cond [value? - (lambda (v) ((error-value->string-handler) v (error-print-width)))] - [else - (lambda (v) (format "~a" v))])] - [convert-value - (if noindent? - (lambda (v indent) (list (convert-value0 v))) - (lambda (v indent) - (let* ([s (convert-value0 v)] - [lines (string-split s #rx"[\n]" #:trim? #f)] - [spacing - (case indent - ((3) "\n ") ;; common case, make constant - (else (string-append "\n" (make-string indent #\space))))]) - (add-between lines spacing))))]) - (cond [(and (or maybe? multi? (not value?)) - (not value)) - null] - [(and maybe? multi? - (null? value)) - null] - [multi? - (list* "\n " field ": " - (let value-loop ([value value]) - (cond [(pair? value) - (list* "\n " - (append (convert-value (car value) 3) - (value-loop (cdr value))))] - [(null? value) - null])))] - [else - (list* "\n " field ": " - (convert-value value (+ 4 (string-length field))))]))) - -;; ---- - -(define (field+detail-list->table who lst onto) - (cond [(null? lst) onto] - [else - (let ([field (car lst)] - [value (cadr lst)]) - (cons (cons field value) - (field+detail-list->table who (cddr lst) onto)))])) - -;; Added by Jay - -(define (exn:not-break? x) - (not (exn:break? x))) - -(define (error-display x) - ((error-display-handler) - (if (exn? x) - (exn-message x) - "non-exn error:") - x)) - -(provide - (contract-out - [exn:not-break? (-> any/c boolean?)] - [error-display (-> any/c void?)])) From 689c294e91a706248d2963b5cb8811ebf9d33d0e Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 13 Sep 2015 13:34:45 -0500 Subject: [PATCH 220/381] Remove dependency on unstable/error. --- .../syntax/parse/private/runtime-report.rkt | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/racket/collects/syntax/parse/private/runtime-report.rkt b/racket/collects/syntax/parse/private/runtime-report.rkt index 0cd3ad2f0a..e129526ec4 100644 --- a/racket/collects/syntax/parse/private/runtime-report.rkt +++ b/racket/collects/syntax/parse/private/runtime-report.rkt @@ -3,7 +3,6 @@ racket/format syntax/stx racket/struct - unstable/error syntax/srcloc "minimatch.rkt" syntax/parse/private/residual @@ -175,6 +174,11 @@ complicated. (define (error/reports ctx reports) (error/report ctx (car reports) (pair? (cdr reports)))) +(define (format-if prefix val) + (if val + (format "\n ~a: ~a" prefix val) + "")) + (define (error/report ctx report more?) (let* ([message (report-message report)] [context (report-context report)] @@ -183,13 +187,18 @@ complicated. [sub-stx (report-stx report)] [within-stx (report-within-stx report)] [message - (compose-error-message - who message - '("at" maybe) (stx-if-loc sub-stx) - '("within" maybe) (stx-if-loc within-stx) - '("in" maybe) (stx-if-loc stx) - '("parsing context" multi maybe) context - '("note" maybe) (and more? "additional errors omitted"))] + (format "~a: ~a~a~a~a~a~a" + who message + (format-if "at" (stx-if-loc sub-stx)) + (format-if "within" (stx-if-loc within-stx)) + (format-if "in" (stx-if-loc stx)) + (if (null? context) + "" + (apply string-append + "\n parsing context: " + (for/list ([c (in-list context)]) + (format "\n ~a" c)))) + (format-if "note" (and more? "additional errors omitted")))] [message (if (error-print-source-location) (let ([source-stx (or stx sub-stx within-stx)]) From aa0823daf613247a9e5a6e874c374af01c0ade95 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 13 Sep 2015 13:45:27 -0500 Subject: [PATCH 221/381] Remove dependencies on unstable/error. Involved moving part of its implementation to the db collection. --- .../collects/db/private/generic/functions.rkt | 1 - .../db/private/generic/interfaces.rkt | 93 ++++++++++++++++++- .../db/private/sqlite3/connection.rkt | 1 - 3 files changed, 91 insertions(+), 4 deletions(-) diff --git a/racket/collects/db/private/generic/functions.rkt b/racket/collects/db/private/generic/functions.rkt index 2bc02e1c2f..16e3fc4be3 100644 --- a/racket/collects/db/private/generic/functions.rkt +++ b/racket/collects/db/private/generic/functions.rkt @@ -2,7 +2,6 @@ (require racket/vector racket/class racket/promise - unstable/error "interfaces.rkt" (only-in "sql-data.rkt" sql-null sql-null?)) (provide connected? diff --git a/racket/collects/db/private/generic/interfaces.rkt b/racket/collects/db/private/generic/interfaces.rkt index 3bf4c8d2a5..f0d656188a 100644 --- a/racket/collects/db/private/generic/interfaces.rkt +++ b/racket/collects/db/private/generic/interfaces.rkt @@ -1,7 +1,8 @@ #lang racket/base (require racket/class + racket/list racket/serialize - unstable/error) + racket/string) (provide connection<%> dbsystem<%> prepared-statement<%> @@ -200,7 +201,95 @@ For SQLite, use symbol instead of SQLSTATE string. error/want-cursor error/column-count error/row-count - error/statement-binding-args) + error/statement-binding-args + ;; other modules also define some error reporting + compose-error-message + error*) + +(define (error* who message + #:continued [continued-message null] + . field+detail-list) + (raise + (exn:fail + (compose* who message + continued-message + (field+detail-list->table 'error* field+detail-list null)) + (current-continuation-marks)))) + +;; compose-error-message : .... -> string +(define (compose-error-message who message + #:continued [continued-message null] + . field+detail-list) + (define details + (field+detail-list->table 'compose-error-message field+detail-list null)) + (compose* who message continued-message details)) + +(define (compose* who message continued-message details) + (let* ([parts (apply append + (for/list ([detail (in-list details)]) + (let* ([field+opts (car detail)] + [field (if (pair? field+opts) (car field+opts) field+opts)] + [options (if (pair? field+opts) (cdr field+opts) '())] + [value (cdr detail)]) + (compose-detail* field options value))))] + [parts (let loop ([continued continued-message]) + (cond [(pair? continued) (list* "\n " (car continued) (loop (cdr continued)))] + [(string? continued) (loop (list continued))] + [(null? continued) parts]))] + [parts (list* message (if (null? continued-message) "" ";") parts)] + [parts (if who + (list* (symbol->string who) ": " parts) + parts)]) + (apply string-append parts))) + +(define (compose-detail* field options value) + (let* ([value? (memq 'value options)] + [multi? (memq 'multi options)] + [maybe? (memq 'maybe options)] + [noindent? (memq 'noindent options)] + [convert-value0 + (cond [value? + (lambda (v) ((error-value->string-handler) v (error-print-width)))] + [else + (lambda (v) (format "~a" v))])] + [convert-value + (if noindent? + (lambda (v indent) (list (convert-value0 v))) + (lambda (v indent) + (let* ([s (convert-value0 v)] + [lines (string-split s #rx"[\n]" #:trim? #f)] + [spacing + (case indent + ((3) "\n ") ;; common case, make constant + (else (string-append "\n" (make-string indent #\space))))]) + (add-between lines spacing))))]) + (cond [(and (or maybe? multi? (not value?)) + (not value)) + null] + [(and maybe? multi? + (null? value)) + null] + [multi? + (list* "\n " field ": " + (let value-loop ([value value]) + (cond [(pair? value) + (list* "\n " + (append (convert-value (car value) 3) + (value-loop (cdr value))))] + [(null? value) + null])))] + [else + (list* "\n " field ": " + (convert-value value (+ 4 (string-length field))))]))) + +(define (field+detail-list->table who lst onto) + (cond [(null? lst) onto] + [else + (let ([field (car lst)] + [value (cadr lst)]) + (cons (cons field value) + (field+detail-list->table who (cddr lst) onto)))])) + (define (error/internal fsym fmt . args) (error* fsym "internal error" diff --git a/racket/collects/db/private/sqlite3/connection.rkt b/racket/collects/db/private/sqlite3/connection.rkt index 59f01c7f6f..29c72ad72e 100644 --- a/racket/collects/db/private/sqlite3/connection.rkt +++ b/racket/collects/db/private/sqlite3/connection.rkt @@ -3,7 +3,6 @@ ffi/unsafe ffi/unsafe/atomic ffi/unsafe/custodian - unstable/error "../generic/interfaces.rkt" "../generic/common.rkt" "../generic/prepared.rkt" From dedde2cd60aedecdebe2468a7c33c491a0082511 Mon Sep 17 00:00:00 2001 From: Benjamin Greenman Date: Sun, 13 Sep 2015 00:45:59 -0400 Subject: [PATCH 222/381] typo: construct -> contract --- pkgs/racket-doc/scribblings/reference/contracts.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 5b386ce3be..298383b243 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -1356,7 +1356,7 @@ if they do not, a contract violation is signaled. Then, when the function returns, it is checked to determine whether the result is wrapped, since the second @racket[a] appears in a positive position. - The @racket[new-∀/c] construct constructor is dual to @racket[new-∃/c]. + The @racket[new-∀/c] contract constructor is dual to @racket[new-∃/c]. } @defproc[(new-∃/c [name (or/c symbol? #f) #f]) contract?]{ From d1ad70b7a0f433d4215b489fcfbf7399ac19be99 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 14 Sep 2015 16:23:57 -0500 Subject: [PATCH 223/381] Remove mention of unstable. --- pkgs/racket-doc/scribblings/style/todo.scrbl | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/style/todo.scrbl b/pkgs/racket-doc/scribblings/style/todo.scrbl index 5bbdb8d8b5..e34165a180 100644 --- a/pkgs/racket-doc/scribblings/style/todo.scrbl +++ b/pkgs/racket-doc/scribblings/style/todo.scrbl @@ -14,6 +14,4 @@ @item{Find and link to good/bad examples in the code base.} -@item{Do we need a discussion of life cycles that start in @tt{unstable}?} - ] From 1e1b6ec32ed0efdbfbd4f01415aef9fdaaa28c8a Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 14 Sep 2015 16:54:06 -0500 Subject: [PATCH 224/381] Remove stray unstable dependency. --- pkgs/racket-test-core/info.rkt | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/racket-test-core/info.rkt b/pkgs/racket-test-core/info.rkt index 02fe4ed48e..09f454eafd 100644 --- a/pkgs/racket-test-core/info.rkt +++ b/pkgs/racket-test-core/info.rkt @@ -5,8 +5,6 @@ ;; Tests that need dependencies belong in the "racket-test" or the ;; "racket-test-extra" packages. (define deps '("base" - ;; the tests use -min.0 etc - "unstable-flonum-lib" ;; the tests use zo-structs "zo-lib" ;; the tests use the scribble reader From 7afdca2c55d4b9cb9088e97621994d213617edb9 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 15 Sep 2015 11:45:58 -0500 Subject: [PATCH 225/381] Remove unused dependencies. --- pkgs/racket-benchmarks/info.rkt | 1 - .../tests/racket/benchmarks/shootout/heapsort.rkt | 3 --- .../tests/racket/benchmarks/shootout/typed/heapsort.rktl | 3 --- 3 files changed, 7 deletions(-) diff --git a/pkgs/racket-benchmarks/info.rkt b/pkgs/racket-benchmarks/info.rkt index 7a8787b6ed..9a3c38bb27 100644 --- a/pkgs/racket-benchmarks/info.rkt +++ b/pkgs/racket-benchmarks/info.rkt @@ -6,7 +6,6 @@ "compatibility-lib" "r5rs-lib" "scheme-lib" - "srfi-lite-lib" "racket-test" "typed-racket-lib" "gui-lib")) diff --git a/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/heapsort.rkt b/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/heapsort.rkt index e44eb500ae..6b61b08401 100644 --- a/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/heapsort.rkt +++ b/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/heapsort.rkt @@ -7,9 +7,6 @@ #lang racket/base -(require (only-in srfi/13 string-index string-pad-right) - (only-in mzlib/string real->decimal-string)) - (define IM 139968) (define IA 3877) (define IC 29573) diff --git a/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/heapsort.rktl b/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/heapsort.rktl index 955ed458e9..f8c03bcaa9 100644 --- a/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/heapsort.rktl +++ b/pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/heapsort.rktl @@ -5,9 +5,6 @@ ;; ;; Updated by Brent Fulgham to provide proper output formatting -(require (only-in srfi/13 string-index string-pad-right) - (only-in mzlib/string real->decimal-string)) - (define IM 139968) (define IA 3877) (define IC 29573) From bcd3d814fd5d75f06665f44e42c63c6684f3c77a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 14 Sep 2015 05:16:11 -0600 Subject: [PATCH 226/381] GC: chunk mrpotect calls on old-page allocation Although a block cache is set up to group most page-protection changes into a single OS call, allocating new old-generation pages was not covered. Adjust the block cache to group those. This change has a small effect on performance, but it seems better to have a few system calls in place of thousands. --- racket/src/racket/gc2/block_cache.c | 91 ++++++++++++++++++++++++----- racket/src/racket/gc2/newgc.c | 8 +-- racket/src/racket/gc2/vm.c | 6 +- racket/src/racket/gc2/weak.c | 2 +- 4 files changed, 87 insertions(+), 20 deletions(-) diff --git a/racket/src/racket/gc2/block_cache.c b/racket/src/racket/gc2/block_cache.c index 9764ce79f2..145d059ab3 100644 --- a/racket/src/racket/gc2/block_cache.c +++ b/racket/src/racket/gc2/block_cache.c @@ -29,10 +29,13 @@ static int block_cache_chain_stat(GCList *head, int *bcnt); #endif struct block_group; + typedef struct block_desc { GCList gclist; void *block; void *free; + unsigned char *protect_map; /* 1 => write protected, 0 => not protected */ + unsigned char *alloc_map; /* 1 => allocated, 0 => not allocated */ intptr_t size; intptr_t used; intptr_t totalcnt; @@ -41,6 +44,11 @@ typedef struct block_desc { int in_queue; } block_desc; +#define BD_BLOCK_PTR_TO_POS(p, bd) (((char *)(p) - (char *)((bd)->block)) >> LOG_APAGE_SIZE) +#define BD_MAP_GET_BIT(map, pos) ((map)[(pos) >> 3] & (1 << ((pos) & 0x7))) +#define BD_MAP_SET_BIT(map, pos) ((map)[(pos) >> 3] |= (1 << ((pos) & 0x7))) +#define BD_MAP_UNSET_BIT(map, pos) ((map)[(pos) >> 3] -= (1 << ((pos) & 0x7))) + typedef struct block_group { GCList full; GCList free; @@ -89,7 +97,6 @@ static block_desc *bc_alloc_std_block(block_group *bg) { void *r = os_alloc_pages(this_block_size); block_desc *bd; void *ps; - if (!r) return NULL; ps = align_up_ptr(r, APAGE_SIZE); @@ -108,6 +115,8 @@ static block_desc *bc_alloc_std_block(block_group *bg) { bd->size = this_block_size; bd->used = 0; bd->group = bg; + bd->protect_map = (unsigned char *)ofm_malloc_zero(this_block_size >> (LOG_APAGE_SIZE + 3)); + bd->alloc_map = (unsigned char *)ofm_malloc_zero(this_block_size >> (LOG_APAGE_SIZE + 3)); gclist_init(&bd->gclist); /* printf("ALLOC BLOCK %p-%p size %li %li %li %p\n", bd->block, bd->block + bd->size, bd->size, APAGE_SIZE, bd->size / APAGE_SIZE, bd->free); */ @@ -179,13 +188,43 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect block_desc *bd = gclist_first_item(free_head, block_desc*, gclist); pfree_list *fl = bd->free; void *p = fl; + int pos = BD_BLOCK_PTR_TO_POS(p, bd); + + GC_ASSERT(pos >= 0); + GC_ASSERT(pos < (bd->size >> LOG_APAGE_SIZE)); + bd->free = fl->next; bd->freecnt--; *src_block = bd; + + BD_MAP_SET_BIT(bd->alloc_map, pos); + if (expect_mprotect) { - GC_MP_CNT_INC(mp_alloc_med_big_cnt); - os_protect_pages(p, APAGE_SIZE, 1); + if (BD_MAP_GET_BIT(bd->protect_map, pos)) { + /* Unprotect a contiguous range of unallocated pages, + in case we need to allocate more, since expanding + the range costs much less than multiple unprotect + calls. */ + int start_pos = pos, end_pos = pos + 1; + while (start_pos + && !BD_MAP_GET_BIT(bd->alloc_map, start_pos) + && BD_MAP_GET_BIT(bd->protect_map, start_pos)) { + BD_MAP_UNSET_BIT(bd->protect_map, start_pos); + --start_pos; + } + while ((end_pos < (bd->size >> LOG_APAGE_SIZE)) + && !BD_MAP_GET_BIT(bd->alloc_map, end_pos) + && BD_MAP_GET_BIT(bd->protect_map, end_pos)) { + BD_MAP_UNSET_BIT(bd->protect_map, end_pos); + end_pos++; + } + + GC_MP_CNT_INC(mp_alloc_med_big_cnt); + os_protect_pages((char *)p - ((pos - start_pos) * APAGE_SIZE), + (end_pos - start_pos) * APAGE_SIZE, + 1); + } } if (!dirty_ok) { @@ -195,9 +234,9 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect fl->next = 0; } + GC_ASSERT(p >= bd->block); + GC_ASSERT(p+APAGE_SIZE <= bd->block + bd->size); #if BC_ASSERTS - assert(p >= bd->block); - assert(p+APAGE_SIZE <= bd->block + bd->size); if (!bg->atomic) { int afub = 0; @@ -220,6 +259,8 @@ static ssize_t bc_free_std_block(block_desc *b) { gclist_del(&b->gclist); os_free_pages(b->block, b->size); size_diff -= b->size; + ofm_free(b->protect_map, b->size >> (LOG_APAGE_SIZE + 3)); + ofm_free(b->alloc_map, b->size >> (LOG_APAGE_SIZE + 3)); ofm_free(b, sizeof(block_desc)); return size_diff; } @@ -252,17 +293,20 @@ static ssize_t block_cache_free_page(BlockCache* bc, void *p, size_t len, int ty int originated_here) { switch(type) { case MMU_SMALL_GEN1: + GC_ASSERT(*src_block != (char*)~0x0); { GCList *free_head = &((expect_mprotect ? &bc->non_atomic : &bc->atomic)->free); block_desc *b = (block_desc*)(*src_block); pfree_list *fl = p; + int pos = BD_BLOCK_PTR_TO_POS(p, b); + GC_ASSERT(b->group == (expect_mprotect ? &bc->non_atomic : &bc->atomic)); + GC_ASSERT(pos >= 0); + GC_ASSERT(pos < (b->size >> LOG_APAGE_SIZE)); fl->next = b->free; fl->dirty = 1; b->free = fl; -#if BC_ASSERTS - assert(*src_block != (char*)~0x0); - assert(b->group == bg); -#endif + GC_ASSERT(BD_MAP_GET_BIT(b->alloc_map, pos)); + BD_MAP_SET_BIT(b->alloc_map, pos); gclist_move(&b->gclist, free_head); b->freecnt++; #if BC_ASSERTS @@ -283,12 +327,12 @@ static ssize_t block_cache_free_page(BlockCache* bc, void *p, size_t len, int ty } break; default: + GC_ASSERT(*src_block == (char*)~0x0); #if BC_ASSERTS assert(!(find_addr_in_bd(&bc->atomic.full, p, "atomic full") || find_addr_in_bd(&bc->atomic.free, p, "atomic freeblock") || find_addr_in_bd(&bc->non_atomic.full, p, "non_atomic full") || find_addr_in_bd(&bc->non_atomic.free, p, "non_atomic freeblock"))); - assert(*src_block == (char*)~0x0); #endif return alloc_cache_free_page(bc->bigBlockCache, p, len, MMU_DIRTY, originated_here); break; @@ -350,6 +394,26 @@ static ssize_t block_cache_flush_freed_pages(BlockCache* bc) { return size_diff + alloc_cache_size_diff; } +static void block_cache_protect_one_page(BlockCache* bc, void *p, size_t len, int type, int writeable, void **src_block) { + switch(type) { + case MMU_SMALL_GEN1: + GC_ASSERT(len == APAGE_SIZE); + { + block_desc *b = (block_desc *)*src_block; + int pos = BD_BLOCK_PTR_TO_POS(p, b); + GC_ASSERT(pos >= 0); + GC_ASSERT(pos < (b->size >> LOG_APAGE_SIZE)); + if (BD_MAP_GET_BIT(b->protect_map, pos)) { + BD_MAP_UNSET_BIT(b->protect_map, pos); + os_protect_pages(p, len, writeable); + } + } + break; + default: + os_protect_pages(p, len, writeable); + } +} + static void block_cache_queue_protect_range(BlockCache* bc, void *p, size_t len, int type, int writeable, void **src_block) { switch(type) { case MMU_SMALL_GEN1: @@ -358,18 +422,17 @@ static void block_cache_queue_protect_range(BlockCache* bc, void *p, size_t len, find_addr_in_bd(&bc->atomic.free, p, "atomic freeblock"))); assert(find_addr_in_bd(&bc->non_atomic.full, p, "non_atomic full") || find_addr_in_bd(&bc->non_atomic.free, p, "non_atomic freeblock")); - assert(*src_block != (char*)~0x0); #endif + GC_ASSERT(*src_block != (char*)~0x0); { block_desc *b = (block_desc *)*src_block; b->in_queue = 1; + memset(b->protect_map, writeable ? 0 : 255, (b->size >> (LOG_APAGE_SIZE + 3))); } return; break; default: -#if BC_ASSERTS - assert(*src_block == (char*)~0x0); -#endif + GC_ASSERT(*src_block == (char*)~0x0); page_range_add(bc->page_range, p, len, writeable); return; break; diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index e049188185..e362f3187b 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2804,7 +2804,7 @@ static int designate_modified_gc(NewGC *gc, void *p) if (page) { page->mprotected = 0; - mmu_write_unprotect_page(gc->mmu, page->addr, real_page_size(page)); + mmu_write_unprotect_page(gc->mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); GC_MP_CNT_INC(mp_write_barrier_cnt); if (!page->back_pointers) set_has_back_pointers(gc, page); @@ -3623,7 +3623,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) } if (work->mprotected) { work->mprotected = 0; - mmu_write_unprotect_page(gc->mmu, work->addr, APAGE_SIZE); + mmu_write_unprotect_page(gc->mmu, work->addr, APAGE_SIZE, page_mmu_type(work), &work->mmu_src_block); GC_MP_CNT_INC(mp_mark_cnt); } newplace = PTR(NUM(work->addr) + work->size); @@ -4235,7 +4235,7 @@ static void mark_backpointers(NewGC *gc) if (work->mprotected) { /* expected only if QUEUED_MPROTECT_IS_PROMISCUOUS && AGE_GEN_0_TO_GEN_HALF(gc) */ work->mprotected = 0; - mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); + mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); } work->marked_from = 1; @@ -5465,7 +5465,7 @@ static void free_gc(NewGC *gc) for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { for (work = gc->med_pages[MED_PAGE_NONATOMIC][i]; work; work = work->next) { if (work->mprotected) - mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work)); + mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); } } diff --git a/racket/src/racket/gc2/vm.c b/racket/src/racket/gc2/vm.c index 6e1a0077b3..92d22f7e40 100644 --- a/racket/src/racket/gc2/vm.c +++ b/racket/src/racket/gc2/vm.c @@ -200,10 +200,14 @@ static int mmu_should_compact_page(MMU *mmu, void **src_block) { return 0; } -static void mmu_write_unprotect_page(MMU *mmu, void *p, size_t len) { +static void mmu_write_unprotect_page(MMU *mmu, void *p, size_t len, int type, void **src_block) { mmu_assert_os_page_aligned(mmu, (size_t)p); mmu_assert_os_page_aligned(mmu, len); +#ifdef USE_BLOCK_CACHE + block_cache_protect_one_page(mmu->block_cache, p, len, type, 1, src_block); +#else os_protect_pages(p, len, 1); +#endif } static void mmu_queue_protect_range(MMU *mmu, void *p, size_t len, int type, int writeable, void **src_block) { diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index f6954989a9..91317889e4 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -215,7 +215,7 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) page = pagemap_find_page(gc->page_maps, wb->secondary_erase); if (page->mprotected) { page->mprotected = 0; - mmu_write_unprotect_page(gc->mmu, page->addr, APAGE_SIZE); + mmu_write_unprotect_page(gc->mmu, page->addr, APAGE_SIZE, page_mmu_type(page), &page->mmu_src_block); GC_MP_CNT_INC(mp_mark_cnt); } From 28047789a922432c49176c661e9347baef9871d1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 14 Sep 2015 10:19:59 -0600 Subject: [PATCH 227/381] remove "array of tagged" GC support The GC supported allocation for an array of objects where the first one provides a tag, but at this point it was used only in some corners. Change those corner and simplify the GC by removing support for arrays of tagged objects. The main corner to clean up is in the handling of a macro-expansion observer and inferred names. Move those into the compile-time environment. It's possible that name inference has been broken by the changes, but in addition to passing the tests, the generated bytecode for the base collections is exactly the same as before the change. --- pkgs/racket-test-core/tests/racket/name.rktl | 3 + racket/src/racket/gc2/README | 8 - racket/src/racket/gc2/gc2.h | 8 +- racket/src/racket/gc2/newgc.c | 65 +- racket/src/racket/include/mzwin3m.def | 1 - racket/src/racket/include/racket3m.exp | 1 - racket/src/racket/include/scheme.h | 3 - racket/src/racket/src/compenv.c | 18 +- racket/src/racket/src/compile.c | 520 +++--- racket/src/racket/src/eval.c | 26 +- racket/src/racket/src/fun.c | 4 +- racket/src/racket/src/mkmark.rkt | 34 +- racket/src/racket/src/module.c | 65 +- racket/src/racket/src/mzmark_compenv.inc | 21 +- racket/src/racket/src/mzmark_eval.inc | 46 +- racket/src/racket/src/mzmark_fun.inc | 85 +- racket/src/racket/src/mzmark_future.inc | 68 +- racket/src/racket/src/mzmark_hash.inc | 17 +- racket/src/racket/src/mzmark_jit.inc | 68 +- racket/src/racket/src/mzmark_letrec_check.inc | 34 +- racket/src/racket/src/mzmark_network.inc | 68 +- racket/src/racket/src/mzmark_optimize.inc | 34 +- racket/src/racket/src/mzmark_place.inc | 102 +- racket/src/racket/src/mzmark_port.inc | 136 +- racket/src/racket/src/mzmark_portfun.inc | 68 +- racket/src/racket/src/mzmark_print.inc | 34 +- racket/src/racket/src/mzmark_read.inc | 102 +- racket/src/racket/src/mzmark_regexp.inc | 51 +- racket/src/racket/src/mzmark_resolve.inc | 34 +- racket/src/racket/src/mzmark_salloc.inc | 34 +- racket/src/racket/src/mzmark_sema.inc | 34 +- racket/src/racket/src/mzmark_sfs.inc | 17 +- racket/src/racket/src/mzmark_string.inc | 17 +- racket/src/racket/src/mzmark_struct.inc | 136 +- racket/src/racket/src/mzmark_syntax.inc | 68 +- racket/src/racket/src/mzmark_thread.inc | 238 ++- racket/src/racket/src/mzmark_type.inc | 1480 +++++++++++++++-- racket/src/racket/src/mzmark_validate.inc | 17 +- racket/src/racket/src/mzmarksrc.c | 31 +- racket/src/racket/src/read.c | 47 - racket/src/racket/src/schemef.h | 1 - racket/src/racket/src/schemex.h | 1 - racket/src/racket/src/schemex.inc | 1 - racket/src/racket/src/schemexm.h | 1 - racket/src/racket/src/schpriv.h | 13 +- racket/src/racket/src/stypes.h | 133 +- racket/src/racket/src/thread.c | 15 - 47 files changed, 3222 insertions(+), 786 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/name.rktl b/pkgs/racket-test-core/tests/racket/name.rktl index d114c5ba0e..03a634be38 100644 --- a/pkgs/racket-test-core/tests/racket/name.rktl +++ b/pkgs/racket-test-core/tests/racket/name.rktl @@ -65,6 +65,9 @@ (test 'w object-name (let ([w (let ([x 5]) (lambda () x))]) w)) (test 'z object-name (let ([z (let ([x 5]) (cons 1 2) (lambda () x))]) z)) +(test 'w object-name (let ([w (let () (lambda () 'x))]) w)) +(test 'z object-name (let ([z (let () (cons 1 2) (lambda () 'x))]) z)) + (set! f (lambda () 10)) (test 'f object-name f) diff --git a/racket/src/racket/gc2/README b/racket/src/racket/gc2/README index 26e29964d6..8db9a74ea2 100644 --- a/racket/src/racket/gc2/README +++ b/racket/src/racket/gc2/README @@ -95,14 +95,6 @@ Racket allocates the following kinds of memory objects: * Array - The allocated object is an array of pointers to other allocated objects. - * Tagged Array - The allocated object is an array of tagged - objects. Every tagged object in the array is the same size and has - the same effective tag. After allocating the memory, Racket sets - the tag on the initial array element, but might not set the tag of - other elements until later. (Even if tags are not set for all - objects, the mark and fixup operations might be applied to all of - them.) - * Pair - specialization of Tagged to pairs. * Interior Array - Like array objects, but pointers to the object can diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index 307ab2c48c..9af444821a 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -204,12 +204,6 @@ GC2_EXTERN void *GC_malloc_pair(void *car, void *cdr); The main potential advantage is that `car' and `cdr' don't have to be retained by the callee in the case of a GC. */ -GC2_EXTERN void *GC_malloc_array_tagged(size_t); -/* - Alloc an array of tagged items. Racket sets the tag in the first - item before a collection, by maybe not all items. When traversing, - use the first one for size. */ - GC2_EXTERN void *GC_malloc_atomic(size_t size_in_bytes); /* Alloc pointerless memory (not necessarily zeroed). */ @@ -605,6 +599,8 @@ GC2_EXTERN void GC_set_backpointer_object(void *p); #define gcBYTES_TO_WORDS(x) ((x + (1 << gcLOG_WORD_SIZE) - 1) >> gcLOG_WORD_SIZE) #define gcWORDS_TO_BYTES(x) (x << gcLOG_WORD_SIZE) +#define GC_NO_SIZE_NEEDED_FROM_PROCS 1 + #define GC_INTERIORABLES_NEVER_MOVE 1 #endif /* __mzscheme_gc_2__ */ diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index e362f3187b..eef4a2b84a 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -80,11 +80,10 @@ enum { PAGE_TAGGED = 0, PAGE_ATOMIC = 1, PAGE_ARRAY = 2, - PAGE_TARRAY = 3, - PAGE_PAIR = 4, - PAGE_BIG = 5, + PAGE_PAIR = 3, + PAGE_BIG = 4, /* the number of page types: */ - PAGE_TYPES = 6 + PAGE_TYPES = 5 }; enum { @@ -128,7 +127,6 @@ static const char *type_name[PAGE_TYPES] = { "tagged", "atomic", "array", - "tagged array", "pair", "big" }; @@ -699,9 +697,6 @@ static void dump_page_map(NewGC *gc, const char *when) case PAGE_ARRAY: kind = 'r'; break; - case PAGE_TARRAY: - kind = 'y'; - break; case PAGE_PAIR: kind = 'p'; break; @@ -1590,7 +1585,6 @@ void *GC_malloc_pair(void *car, void *cdr) /* the allocation mechanism we present to the outside world */ void *GC_malloc(size_t s) { return allocate(s, PAGE_ARRAY); } void *GC_malloc_one_tagged(size_t s) { return allocate(s, PAGE_TAGGED); } -void *GC_malloc_array_tagged(size_t s) { return allocate(s, PAGE_TARRAY); } void *GC_malloc_atomic(size_t s) { return allocate(s, PAGE_ATOMIC); } void *GC_malloc_atomic_uncollectable(size_t s) { return ofm_malloc_zero(s); } void *GC_malloc_allow_interior(size_t s) { return allocate_medium(s, PAGE_ARRAY); } @@ -3748,17 +3742,6 @@ static inline void propagate_marks_worker(NewGC *gc, void *pp) { while(start < end) gcMARK2(*start++, gc); break; } - case PAGE_TARRAY: - { - const unsigned short tag = *(unsigned short *)start; - ASSERT_TAG(tag); - end -= INSET_WORDS; - while(start < end) { - GC_ASSERT(gc->mark_table[tag]); - start += gc->mark_table[tag](start, gc); - } - break; - } case PAGE_PAIR: { Scheme_Object *p = (Scheme_Object *)start; @@ -3897,7 +3880,6 @@ static void *trace_pointer_start(mpage *page, void *p) { } # define TRACE_PAGE_TAGGED PAGE_TAGGED # define TRACE_PAGE_ARRAY PAGE_ARRAY -# define TRACE_PAGE_TAGGED_ARRAY PAGE_TARRAY # define TRACE_PAGE_ATOMIC PAGE_ATOMIC # define TRACE_PAGE_PAIR PAGE_PAIR # define TRACE_PAGE_MALLOCFREE PAGE_TYPES @@ -3910,7 +3892,6 @@ const char *trace_source_kind(int kind) case PAGE_TAGGED: return "_TAGGED"; case PAGE_ATOMIC: return "_ATOMIC"; case PAGE_ARRAY: return "_ARRAY"; - case PAGE_TARRAY: return "_TARRAY"; case PAGE_PAIR: return "_PAIR"; case PAGE_BIG: return "_BIG"; case BT_STACK: return "STACK"; @@ -4460,18 +4441,6 @@ static int repair_mixed_page(NewGC *gc, mpage *page, void **end) case PAGE_ATOMIC: start += info->size; break; - case PAGE_TARRAY: - { - void **tempstart, **tempend = PPTR(info) + (info->size - INSET_WORDS); - unsigned short tag; - tempstart = OBJHEAD_TO_OBJPTR(start); - tag = *(unsigned short*)tempstart; - ASSERT_TAG(tag); - while (tempstart < tempend) - tempstart += fixup_table[tag](tempstart, gc); - start += info->size; - } - break; case PAGE_PAIR: { Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); @@ -4625,14 +4594,6 @@ static void repair_heap(NewGC *gc) gcFIXUP2(SCHEME_CDR(p), gc); } break; - case PAGE_TARRAY: - { - unsigned short tag = *(unsigned short *)start; - ASSERT_TAG(tag); - end -= INSET_WORDS; - while(start < end) start += fixup_table[tag](start, gc); - break; - } } memory_in_use += page->size; @@ -4683,26 +4644,6 @@ static void repair_heap(NewGC *gc) } } break; - case PAGE_TARRAY: - while(start < end) { - objhead *info = (objhead *)start; - size_t size = info->size; - if(info->mark) { - void **tempend = PPTR(info) + (info->size - INSET_WORDS); - unsigned short tag; - start = OBJHEAD_TO_OBJPTR(start); - tag = *(unsigned short*)start; - ASSERT_TAG(tag); - while(start < tempend) - start += fixup_table[tag](start, gc); - info->mark = 0; - start = PPTR(info) + size; - } else { - info->dead = 1; - start += size; - } - } - break; case PAGE_PAIR: while(start < end) { objhead *info = (objhead *)start; diff --git a/racket/src/racket/include/mzwin3m.def b/racket/src/racket/include/mzwin3m.def index eff2ac2b08..844b694200 100644 --- a/racket/src/racket/include/mzwin3m.def +++ b/racket/src/racket/include/mzwin3m.def @@ -204,7 +204,6 @@ EXPORTS GC_malloc_one_tagged GC_malloc_atomic_uncollectable scheme_malloc_uncollectable - GC_malloc_array_tagged GC_malloc_allow_interior GC_malloc_atomic_allow_interior GC_malloc_tagged_allow_interior diff --git a/racket/src/racket/include/racket3m.exp b/racket/src/racket/include/racket3m.exp index 6a2642d1d8..84d9b9c58f 100644 --- a/racket/src/racket/include/racket3m.exp +++ b/racket/src/racket/include/racket3m.exp @@ -211,7 +211,6 @@ GC_malloc_atomic GC_malloc_one_tagged GC_malloc_atomic_uncollectable scheme_malloc_uncollectable -GC_malloc_array_tagged GC_malloc_allow_interior GC_malloc_atomic_allow_interior GC_malloc_tagged_allow_interior diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 7170a8eb3e..35d6cf7111 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1221,9 +1221,6 @@ typedef struct Scheme_Thread { short suspend_break; short external_break; - Scheme_Simple_Object *list_stack; - int list_stack_pos; - /* Racket client can use: */ void (*on_kill)(struct Scheme_Thread *p); void *kill_data; diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index c718f3ad9e..841ef961b3 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -98,15 +98,9 @@ void scheme_init_compile_recs(Scheme_Compile_Info *src, int drec, int i; for (i = 0; i < n; i++) { -#ifdef MZTAG_REQUIRED - dest[i].type = scheme_rt_compile_info; -#endif dest[i].comp = 1; dest[i].dont_mark_local_use = src[drec].dont_mark_local_use; dest[i].resolve_module_ids = src[drec].resolve_module_ids; - dest[i].value_name = scheme_false; - /* should be always NULL */ - dest[i].observer = src[drec].observer; dest[i].pre_unwrapped = 0; dest[i].testing_constantness = 0; dest[i].env_already = 0; @@ -120,13 +114,8 @@ void scheme_init_expand_recs(Scheme_Expand_Info *src, int drec, int i; for (i = 0; i < n; i++) { -#ifdef MZTAG_REQUIRED - dest[i].type = scheme_rt_compile_info; -#endif dest[i].comp = 0; dest[i].depth = src[drec].depth; - dest[i].value_name = scheme_false; - dest[i].observer = src[drec].observer; dest[i].pre_unwrapped = 0; dest[i].substitute_bindings = src[drec].substitute_bindings; dest[i].testing_constantness = 0; @@ -144,15 +133,10 @@ void scheme_merge_compile_recs(Scheme_Compile_Info *src, int drec, void scheme_init_lambda_rec(Scheme_Compile_Info *src, int drec, Scheme_Compile_Info *lam, int dlrec) { -#ifdef MZTAG_REQUIRED - lam[dlrec].type = scheme_rt_compile_info; -#endif lam[dlrec].comp = 1; lam[dlrec].dont_mark_local_use = src[drec].dont_mark_local_use; lam[dlrec].resolve_module_ids = src[drec].resolve_module_ids; lam[dlrec].substitute_bindings = src[dlrec].substitute_bindings; - lam[dlrec].value_name = scheme_false; - lam[dlrec].observer = src[drec].observer; lam[dlrec].pre_unwrapped = 0; lam[dlrec].testing_constantness = 0; lam[dlrec].env_already = 0; @@ -166,7 +150,6 @@ void scheme_merge_lambda_rec(Scheme_Compile_Info *src, int drec, void scheme_compile_rec_done_local(Scheme_Compile_Info *rec, int drec) { - rec[drec].value_name = scheme_false; } /**********************************************************************/ @@ -285,6 +268,7 @@ Scheme_Comp_Env *scheme_new_compilation_frame(int num_bindings, int flags, Schem frame->insp = base->insp; frame->prefix = base->prefix; frame->in_modidx = base->in_modidx; + frame->observer = base->observer; if (base->next) frame->skip_depth = base->skip_depth + 1; diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index c2bff0ce34..49426e71a0 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -546,7 +546,7 @@ Scheme_Object *combine_name_with_srcloc(Scheme_Object *name, Scheme_Object *code return name; } -Scheme_Object *scheme_build_closure_name(Scheme_Object *code, Scheme_Compile_Info *rec, int drec) +Scheme_Object *scheme_build_closure_name(Scheme_Object *code, Scheme_Comp_Env *env) { Scheme_Object *name; @@ -558,7 +558,7 @@ Scheme_Object *scheme_build_closure_name(Scheme_Object *code, Scheme_Compile_Inf if (name) name = combine_name_with_srcloc(name, code, 1); } else { - name = rec[drec].value_name; + name = env->value_name; if (!name || SCHEME_FALSEP(name)) { name = scheme_source_to_name(code); if (name) @@ -627,7 +627,7 @@ make_closure_compilation(Scheme_Comp_Env *env, Scheme_Object *code, forms = scheme_datum_to_syntax(forms, code, code, 0, 0); forms = scheme_stx_add_scope(forms, scope, scheme_env_phase(env->genv)); - name = scheme_build_closure_name(code, rec, drec); + name = scheme_build_closure_name(code, env); data->name = name; scheme_compile_rec_done_local(rec, drec); @@ -678,7 +678,7 @@ lambda_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info Scheme_Comp_Env *newenv; Scheme_Expand_Info erec1; - SCHEME_EXPAND_OBSERVE_PRIM_LAMBDA(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_LAMBDA(env->observer); form = lambda_check(orig_form); @@ -698,12 +698,11 @@ lambda_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info body = scheme_stx_add_scope(body, scope, scheme_env_phase(env->genv)); args = scheme_stx_add_scope(args, scope, scheme_env_phase(env->genv)); /* for re-expansion */ - SCHEME_EXPAND_OBSERVE_LAMBDA_RENAMES(erec[drec].observer, args, body); + SCHEME_EXPAND_OBSERVE_LAMBDA_RENAMES(env->observer, args, body); fn = SCHEME_STX_CAR(form); scheme_init_expand_recs(erec, drec, &erec1, 1); - erec1.value_name = scheme_false; return scheme_datum_to_syntax(cons(fn, cons(args, @@ -880,7 +879,7 @@ defn_targets_syntax (Scheme_Object *var, Scheme_Comp_Env *env, Scheme_Compile_In static Scheme_Object * define_values_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec) { - Scheme_Object *var, *val, *targets, *variables, *vec; + Scheme_Object *var, *val, *targets, *variables, *vec, *value_name; scheme_define_parse(form, &var, &val, 0, env, 0); variables = var; @@ -890,8 +889,9 @@ define_values_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_ scheme_compile_rec_done_local(rec, drec); if (SCHEME_STX_PAIRP(targets) && SCHEME_STX_NULLP(SCHEME_STX_CDR(targets))) { var = SCHEME_STX_CAR(variables); - rec[drec].value_name = SCHEME_STX_SYM(var); - } + value_name = SCHEME_STX_SYM(var); + } else + value_name = NULL; #if 0 if (env->scopes) @@ -902,9 +902,12 @@ define_values_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_ #endif env = scheme_no_defines(env); + env->value_name = value_name; val = scheme_compile_expr(val, env, rec, drec); + env->value_name = NULL; + vec = scheme_make_vector(2, NULL); SCHEME_VEC_ELS(vec)[0] = targets; SCHEME_VEC_ELS(vec)[1] = val; @@ -923,7 +926,7 @@ define_values_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_In { Scheme_Object *var, *val, *fn, *boundname; - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(env->observer); scheme_define_parse(form, &var, &val, 0, env, 0); @@ -933,16 +936,20 @@ define_values_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_In boundname = SCHEME_STX_CAR(var); else boundname = scheme_false; - erec[drec].value_name = boundname; + env->value_name = boundname; fn = SCHEME_STX_CAR(form); - return scheme_datum_to_syntax(cons(fn, - cons(var, - cons(scheme_expand_expr(val, env, erec, drec), - scheme_null))), + form = scheme_datum_to_syntax(cons(fn, + cons(var, + cons(scheme_expand_expr(val, env, erec, drec), + scheme_null))), form, form, 0, 2); + + env->value_name = NULL; + + return form; } /**********************************************************************/ @@ -974,7 +981,7 @@ quote_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec { Scheme_Object *rest; - SCHEME_EXPAND_OBSERVE_PRIM_QUOTE(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_QUOTE(env->observer); rest = SCHEME_STX_CDR(form); @@ -1035,7 +1042,8 @@ if_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, len = check_form(form, form); check_if_len(form, len); - name = rec[drec].value_name; + name = env->value_name; + env->value_name = NULL; scheme_compile_rec_done_local(rec, drec); name = scheme_check_name_property(form, name); @@ -1051,8 +1059,6 @@ if_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, elsep = scheme_compiled_void(); scheme_init_compile_recs(rec, drec, recs, 3); - recs[1].value_name = name; - recs[2].value_name = name; env = scheme_no_defines(env); @@ -1064,26 +1070,33 @@ if_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, if (SCHEME_FALSEP(test)) { /* compile other branch only to get syntax checking: */ recs[2].dont_mark_local_use = 1; + env->value_name = name; scheme_compile_expr(thenp, env, recs, 2); - - if (len == 4) + + if (len == 4) { + env->value_name = name; test = scheme_compile_expr(elsep, env, recs, 1); - else + } else test = elsep; } else { if (len == 4) { /* compile other branch only to get syntax checking: */ recs[2].dont_mark_local_use = 1; + env->value_name = name; scheme_compile_expr(elsep, env, recs, 2); } - + + env->value_name = name; test = scheme_compile_expr(thenp, env, recs, 1); } } else { opt = 0; + env->value_name = name; thenp = scheme_compile_expr(thenp, env, recs, 1); - if (len == 4) + if (len == 4) { + env->value_name = name; elsep = scheme_compile_expr(elsep, env, recs, 2); + } } scheme_merge_compile_recs(rec, drec, recs, (opt || (len == 3)) ? 2 : 3); @@ -1101,7 +1114,7 @@ if_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *er int len; Scheme_Expand_Info recs[3]; - SCHEME_EXPAND_OBSERVE_PRIM_IF(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_IF(env->observer); form = scheme_stx_taint_disarm(orig_form, NULL); @@ -1110,31 +1123,31 @@ if_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *er check_if_len(form, len); if (len == 3) { - SCHEME_EXPAND_OBSERVE_NEXT_GROUP(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT_GROUP(env->observer); } - env = scheme_no_defines(env); + boundname = scheme_check_name_property(form, env->value_name); - boundname = scheme_check_name_property(form, erec[drec].value_name); + env = scheme_no_defines(env); + env->value_name = NULL; scheme_init_expand_recs(erec, drec, recs, 3); - recs[0].value_name = scheme_false; - recs[1].value_name = boundname; - recs[2].value_name = boundname; rest = SCHEME_STX_CDR(form); test = SCHEME_STX_CAR(rest); test = scheme_expand_expr(test, env, recs, 0); - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); rest = SCHEME_STX_CDR(rest); thenp = SCHEME_STX_CAR(rest); + env->value_name = boundname; thenp = scheme_expand_expr(thenp, env, recs, 1); rest = SCHEME_STX_CDR(rest); if (!SCHEME_STX_NULLP(rest)) { - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); elsep = SCHEME_STX_CAR(rest); + env->value_name = boundname; elsep = scheme_expand_expr(elsep, env, recs, 2); rest = cons(elsep, scheme_null); } else { @@ -1156,7 +1169,7 @@ if_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *er static Scheme_Object * with_cont_mark_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec) { - Scheme_Object *key, *val, *expr, *name, *orig_form = form; + Scheme_Object *key, *val, *expr, *name, *orig_form = form, *value_name; Scheme_Compile_Info recs[3]; Scheme_With_Continuation_Mark *wcm; int len; @@ -1168,7 +1181,9 @@ with_cont_mark_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_ if (len != 4) bad_form(form, len); + value_name = env->value_name; env = scheme_no_defines(env); + env->value_name = NULL; form = SCHEME_STX_CDR(form); key = SCHEME_STX_CAR(form); @@ -1177,16 +1192,16 @@ with_cont_mark_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_ form = SCHEME_STX_CDR(form); expr = SCHEME_STX_CAR(form); - name = rec[drec].value_name; scheme_compile_rec_done_local(rec, drec); - name = scheme_check_name_property(orig_form, name); + name = scheme_check_name_property(orig_form, value_name); scheme_init_compile_recs(rec, drec, recs, 3); - recs[2].value_name = name; key = scheme_compile_expr(key, env, recs, 0); val = scheme_compile_expr(val, env, recs, 1); + + env->value_name = value_name; expr = scheme_compile_expr(expr, env, recs, 2); scheme_merge_compile_recs(rec, drec, recs, 3); @@ -1207,7 +1222,7 @@ with_cont_mark_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Exp int len; Scheme_Expand_Info recs[3]; - SCHEME_EXPAND_OBSERVE_PRIM_WCM(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_WCM(env->observer); form = scheme_stx_taint_disarm(orig_form, NULL); @@ -1217,14 +1232,12 @@ with_cont_mark_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Exp fn = SCHEME_STX_CAR(form); - env = scheme_no_defines(env); + boundname = scheme_check_name_property(form, env->value_name); - boundname = scheme_check_name_property(form, erec[drec].value_name); + env = scheme_no_defines(env); + env->value_name = NULL; scheme_init_expand_recs(erec, drec, recs, 3); - recs[0].value_name = scheme_false; - recs[1].value_name = scheme_false; - recs[2].value_name = boundname; form = SCHEME_STX_CDR(form); key = SCHEME_STX_CAR(form); @@ -1234,9 +1247,10 @@ with_cont_mark_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Exp expr = SCHEME_STX_CAR(form); key = scheme_expand_expr(key, env, recs, 0); - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); val = scheme_expand_expr(val, env, recs, 1); - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + env->value_name = boundname; expr = scheme_expand_expr(expr, env, recs, 2); return scheme_datum_to_syntax(cons(fn, @@ -1321,9 +1335,13 @@ set_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, } scheme_compile_rec_done_local(rec, drec); - rec[drec].value_name = SCHEME_STX_SYM(name); - val = scheme_compile_expr(body, scheme_no_defines(env), rec, drec); + env = scheme_no_defines(env); + env->value_name = SCHEME_STX_SYM(name); + + val = scheme_compile_expr(body, env, rec, drec); + + env->value_name = NULL; set_undef = (rec[drec].comp_flags & COMP_ALLOW_SET_UNDEFINED); @@ -1343,7 +1361,7 @@ set_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *e Scheme_Object *name, *var, *fn, *rhs, *find_name, *form, *binding_id; int l; - SCHEME_EXPAND_OBSERVE_PRIM_SET(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_SET(env->observer); form = scheme_stx_taint_disarm(orig_form, NULL); @@ -1369,22 +1387,22 @@ set_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *e &binding_id, NULL, NULL); - SCHEME_EXPAND_OBSERVE_RESOLVE(erec[drec].observer, find_name); + SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer, find_name); if ((erec[drec].depth != 0) && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type)) { /* Redirect to a macro? */ if (scheme_is_set_transformer(SCHEME_PTR_VAL(var))) { - SCHEME_EXPAND_OBSERVE_ENTER_MACRO(erec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_MACRO(env->observer, form); form = scheme_apply_macro(name, menv, SCHEME_PTR_VAL(var), form, env, scheme_false, erec, drec, 1, 0); - SCHEME_EXPAND_OBSERVE_EXIT_MACRO(erec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_MACRO(env->observer, form); if (erec[drec].depth > 0) erec[drec].depth--; - erec[drec].value_name = name; + env->value_name = name; return scheme_expand_expr(form, env, erec, drec); } else if (scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { @@ -1407,7 +1425,7 @@ set_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *e scheme_wrong_syntax(NULL, name, form, "cannot mutate syntax identifier"); } - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); fn = SCHEME_STX_CAR(form); @@ -1415,16 +1433,20 @@ set_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *e rhs = SCHEME_STX_CDR(rhs); rhs = SCHEME_STX_CAR(rhs); - erec[drec].value_name = name; + env->value_name = name; rhs = scheme_expand_expr(rhs, env, erec, drec); - return scheme_datum_to_syntax(cons(fn, - cons(find_name, - cons(rhs, scheme_null))), + form = scheme_datum_to_syntax(cons(fn, + cons(find_name, + cons(rhs, scheme_null))), orig_form, orig_form, 0, 2); + + env->value_name = NULL; + + return form; } /**********************************************************************/ @@ -1486,6 +1508,7 @@ ref_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, if (SCHEME_STX_PAIRP(name)) { /* FIXME: when using #%top, need to set mutated flag */ + env->value_name = NULL; if (rec[drec].comp) var = scheme_compile_expr(name, env, rec, drec); else @@ -1550,7 +1573,7 @@ ref_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, { Scheme_Object *naya; - SCHEME_EXPAND_OBSERVE_PRIM_VARREF(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_VARREF(env->observer); /* Error checking, and lexical variable update: */ naya = ref_syntax(form, env, erec, drec); @@ -1640,7 +1663,7 @@ case_lambda_syntax (Scheme_Object *form, Scheme_Comp_Env *env, form = SCHEME_STX_CDR(form); - name = scheme_build_closure_name(orig_form, rec, drec); + name = scheme_build_closure_name(orig_form, env); if (SCHEME_STX_NULLP(form)) { /* Case where there are no cases... */ @@ -1715,9 +1738,11 @@ case_lambda_syntax (Scheme_Object *form, Scheme_Comp_Env *env, cl->name = SCHEME_TRUEP(name) ? name : NULL; scheme_compile_rec_done_local(rec, drec); - recs = MALLOC_N_RT(Scheme_Compile_Info, count); + recs = MALLOC_N_ATOMIC(Scheme_Compile_Info, count); scheme_init_compile_recs(rec, drec, recs, count); + env->value_name = NULL; + for (i = 0; i < count; i++) { Scheme_Object *ce; ce = SCHEME_CAR(list); @@ -1750,7 +1775,7 @@ case_lambda_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand { Scheme_Object *first, *last, *args, *body, *c, *new_line, *form; - SCHEME_EXPAND_OBSERVE_PRIM_CASE_LAMBDA(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_CASE_LAMBDA(env->observer); form = scheme_stx_taint_disarm(orig_form, NULL); @@ -1763,7 +1788,7 @@ case_lambda_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand Scheme_Object *line_form, *scope; Scheme_Comp_Env *newenv; - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); line_form = SCHEME_STX_CAR(form); @@ -1781,12 +1806,11 @@ case_lambda_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand body = scheme_stx_add_scope(body, scope, scheme_env_phase(env->genv)); args = scheme_stx_add_scope(args, scope, scheme_env_phase(env->genv)); - SCHEME_EXPAND_OBSERVE_CASE_LAMBDA_RENAMES(erec[drec].observer, args, body); + SCHEME_EXPAND_OBSERVE_CASE_LAMBDA_RENAMES(env->observer, args, body); { Scheme_Expand_Info erec1; scheme_init_expand_recs(erec, drec, &erec1, 1); - erec1.value_name = scheme_false; new_line = cons(args, expand_block(body, newenv, &erec1, 0)); } new_line = scheme_datum_to_syntax(new_line, line_form, line_form, 0, 1); @@ -2251,8 +2275,8 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname, env = scheme_new_compilation_frame(0, 0, scope, origenv); forms = scheme_stx_add_scope(forms, scope, scheme_env_phase(env->genv)); - name = scheme_check_name_property(form, rec[drec].value_name); - rec[drec].value_name = name; + name = scheme_check_name_property(form, origenv->value_name); + env->value_name = name; return compile_sequence(forms, env, rec, drec, body_block); } @@ -2316,9 +2340,9 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname, else rhs_env = env; - recs = MALLOC_N_RT(Scheme_Compile_Info, (num_clauses + 1)); + recs = MALLOC_N_ATOMIC(Scheme_Compile_Info, (num_clauses + 1)); - defname = rec[drec].value_name; + defname = origenv->value_name; scheme_compile_rec_done_local(rec, drec); scheme_init_compile_recs(rec, drec, recs, num_clauses + 1); @@ -2418,7 +2442,7 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname, } if (lv->count == 1) - recs[i].value_name = SCHEME_STX_SYM(names[pre_k]); + rhs_env->value_name = SCHEME_STX_SYM(names[pre_k]); if (!recursive) { Scheme_Object *ce, *rhs; @@ -2432,6 +2456,8 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname, rhs = SCHEME_STX_CAR(rhs); lv->value = rhs; } + + rhs_env->value_name = NULL; if (recursive) { for (m = pre_k; m < k; m++) { @@ -2465,7 +2491,12 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname, rhs = lv->value; if (scope) rhs = scheme_stx_add_scope(rhs, scope, scheme_env_phase(env->genv)); + if (lv->count == 1) + env->value_name = lv->names[0]; + else + env->value_name = NULL; ce = scheme_compile_expr(rhs, env, recs, i); + env->value_name = NULL; lv->value = ce; /* Record the fact that this binding doesn't use any or later @@ -2528,13 +2559,15 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname, else already_compiled_body = 0; - recs[num_clauses].value_name = defname ? SCHEME_STX_SYM(defname) : NULL; + + env->value_name = defname ? SCHEME_STX_SYM(defname) : NULL; { Scheme_Object *cs; if (scope) forms = scheme_stx_add_scope(forms, scope, scheme_env_phase(env->genv)); cs = compile_sequence(forms, env, recs, num_clauses, body_block); last->body = cs; } + env->value_name = NULL; /* Save flags: */ lv = (Scheme_Compiled_Let_Value *)first; @@ -2649,8 +2682,7 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ ? "empty body not allowed" : NULL)); - boundname = scheme_check_name_property(form, erec[drec].value_name); - erec[drec].value_name = boundname; + boundname = scheme_check_name_property(form, origenv->value_name); if (!env_already && !rec_env_already) scheme_begin_dup_symbol_check(&r, origenv); @@ -2755,7 +2787,7 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ body = scheme_datum_to_syntax(body, form, form, 0, 0); if (scope) body = scheme_stx_add_scope(body, scope, scheme_env_phase(env->genv)); - SCHEME_EXPAND_OBSERVE_LET_RENAMES(erec[drec].observer, vars, body); + SCHEME_EXPAND_OBSERVE_LET_RENAMES(env->observer, vars, body); /* Pass 2: Expand */ @@ -2764,7 +2796,7 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ while (SCHEME_STX_PAIRP(vars)) { Scheme_Object *rhs, *rhs_name; - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); v = SCHEME_STX_CAR(vars); @@ -2779,8 +2811,9 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ } scheme_init_expand_recs(erec, drec, &erec1, 1); - erec1.value_name = rhs_name; + use_env->value_name = rhs_name; rhs = scheme_expand_expr(rhs, use_env, &erec1, 0); + use_env->value_name = NULL; v = scheme_datum_to_syntax(cons(name, cons(rhs, scheme_null)), v, v, 0, 1); v = cons(v, scheme_null); @@ -2827,14 +2860,15 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ first = scheme_datum_to_syntax(first, vs, vs, 0, 1); } - SCHEME_EXPAND_OBSERVE_NEXT_GROUP(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT_GROUP(env->observer); scheme_init_expand_recs(erec, drec, &erec1, 1); - erec1.value_name = erec[drec].value_name; + env->value_name = boundname; if (!body_block) body = expand_list(body, env, &erec1, 0); else body = expand_block(body, env, &erec1, 0); - + env->value_name = NULL; + if (SCHEME_PAIRP(pre_set)) { if (first) pre_set = cons(cons(letrec_values_symbol, first), pre_set); @@ -2860,14 +2894,14 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ static Scheme_Object * let_values_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_LET_VALUES(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_LET_VALUES(env->observer); return do_let_expand(form, env, erec, drec, "let-values", 0, 1, NULL); } static Scheme_Object * letrec_values_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_LETREC_VALUES(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_LETREC_VALUES(env->observer); return do_let_expand(form, env, erec, drec, "letrec-values", 1, 1, NULL); } @@ -2919,7 +2953,7 @@ do_begin_syntax(char *name, Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec, int zero) { - Scheme_Object *forms, *body; + Scheme_Object *forms, *body, *vname; form = scheme_stx_taint_disarm(form, NULL); @@ -2934,8 +2968,11 @@ do_begin_syntax(char *name, check_form(form, form); - if (zero) + if (zero) { + vname = env->value_name; env = scheme_no_defines(env); + env->value_name = vname; + } /* if the begin has only one expression inside, drop the begin TODO: is this right */ @@ -2951,16 +2988,17 @@ do_begin_syntax(char *name, Scheme_Compile_Info recs[2]; Scheme_Object *first, *rest, *vname; - vname = rec[drec].value_name; + vname = env->value_name; scheme_compile_rec_done_local(rec, drec); vname = scheme_check_name_property(form, vname); scheme_init_compile_recs(rec, drec, recs, 2); - recs[0].value_name = vname; first = SCHEME_STX_CAR(forms); + env->value_name = vname; first = scheme_compile_expr(first, env, recs, 0); + env->value_name = NULL; rest = SCHEME_STX_CDR(forms); rest = compile_list(rest, env, recs, 1); @@ -2969,10 +3007,12 @@ do_begin_syntax(char *name, body = cons(first, rest); } else { Scheme_Object *v; - v = scheme_check_name_property(form, rec[drec].value_name); - rec[drec].value_name = v; + v = scheme_check_name_property(form, env->value_name); + env->value_name = v; body = compile_list(forms, env, rec, drec); + + env->value_name = NULL; } } else { /* Top level */ @@ -3140,8 +3180,8 @@ do_begin_expand(char *name, if (SCHEME_STX_NULLP(rest)) { if (!zero && scheme_is_toplevel(env)) { - SCHEME_EXPAND_OBSERVE_ENTER_LIST(erec[drec].observer, form); - SCHEME_EXPAND_OBSERVE_EXIT_LIST(erec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_LIST(env->observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_LIST(env->observer, form); return orig_form; } scheme_wrong_syntax(NULL, NULL, form, "empty form not allowed"); @@ -3157,23 +3197,23 @@ do_begin_expand(char *name, Scheme_Object *fst, *boundname; Scheme_Expand_Info erec1; scheme_init_expand_recs(erec, drec, &erec1, 1); - boundname = scheme_check_name_property(form, erec[drec].value_name); - erec1.value_name = boundname; - erec[drec].value_name = scheme_false; + boundname = scheme_check_name_property(form, env->value_name); fst = SCHEME_STX_CAR(rest); rest = SCHEME_STX_CDR(rest); - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + env->value_name = boundname; fst = scheme_expand_expr(fst, env, &erec1, 0); + env->value_name = NULL; rest = scheme_datum_to_syntax(rest, form, form, 0, 0); - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); rest = expand_list(rest, env, erec, drec); form = cons(fst, rest); } else { Scheme_Object *boundname; - boundname = scheme_check_name_property(form, erec[drec].value_name); - erec[drec].value_name = boundname; + boundname = scheme_check_name_property(form, env->value_name); + env->value_name = boundname; form = expand_list(scheme_datum_to_syntax(rest, form, form, 0, 0), env, erec, drec); @@ -3196,14 +3236,14 @@ do_begin_expand(char *name, static Scheme_Object * begin_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(env->observer); return do_begin_expand("begin", form, env, erec, drec, 0); } static Scheme_Object * begin0_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN0(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN0(env->observer); return do_begin_expand("begin0", form, env, erec, drec, 1); } @@ -3212,7 +3252,7 @@ stratified_body_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Ex { Scheme_Object *body, *form; - SCHEME_EXPAND_OBSERVE_PRIM_STRATIFIED(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_STRATIFIED(env->observer); form = scheme_stx_taint_disarm(orig_form, NULL); @@ -3276,7 +3316,7 @@ single_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info if (simplify && (erec[drec].depth == -1)) { expr = scheme_stx_track(expr, form, form_name); - SCHEME_EXPAND_OBSERVE_TAG(erec[drec].observer,expr); + SCHEME_EXPAND_OBSERVE_TAG(env->observer,expr); return expr; } @@ -3292,7 +3332,7 @@ static Scheme_Object *expression_syntax(Scheme_Object *form, Scheme_Comp_Env *en static Scheme_Object *expression_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_EXPRESSION(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_EXPRESSION(env->observer); return single_expand(form, scheme_no_defines(env), erec, drec, 0, !(env->flags & SCHEME_TOPLEVEL_FRAME)); } @@ -3404,7 +3444,7 @@ quote_syntax_syntax(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Compi static Scheme_Object * quote_syntax_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_QUOTE_SYNTAX(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_QUOTE_SYNTAX(env->observer); return quote_syntax_syntax(form, env, erec, drec); } @@ -3419,8 +3459,6 @@ static void prep_exp_env_compile_rec(Scheme_Compile_Info *rec, int drec) rec[0].dont_mark_local_use = 0; rec[0].resolve_module_ids = 0; rec[0].substitute_bindings = 1; - rec[0].value_name = NULL; - rec[0].observer = NULL; rec[0].pre_unwrapped = 0; rec[0].testing_constantness = 0; rec[0].env_already = 0; @@ -3454,11 +3492,15 @@ do_define_syntaxes_syntax(Scheme_Object *form, Scheme_Comp_Env *env, names = scheme_named_map_1(NULL, stx_val, names, (Scheme_Object *)env); exp_env = scheme_new_comp_env(env->genv->exp_env, env->insp, NULL, 0); + exp_env->observer = env->observer; dummy = scheme_make_environment_dummy(env); prep_exp_env_compile_rec(&rec1, 0); + if (SCHEME_PAIRP(names) && SCHEME_NULLP(SCHEME_CDR(names))) + exp_env->value_name = SCHEME_STX_VAL(SCHEME_CAR(names)); + val = scheme_compile_expr_lift_to_let(code, exp_env, &rec1, 0); vec = scheme_make_vector(4, NULL); @@ -3484,9 +3526,9 @@ define_syntaxes_syntax(Scheme_Object *form, Scheme_Comp_Env *env, static Scheme_Object * define_syntaxes_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - Scheme_Object *names, *code, *fpart, *fn, *form; + Scheme_Object *names, *code, *fpart, *fn, *form, *observer; - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(env->observer); form = orig_form; @@ -3494,14 +3536,16 @@ define_syntaxes_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Ex code = scheme_revert_use_site_scopes(code, env); - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); scheme_prepare_exp_env(env->genv); scheme_prepare_compile_env(env->genv->exp_env); + observer = env->observer; env = scheme_new_expand_env(env->genv->exp_env, env->insp, NULL, 0); + env->observer = observer; - erec[drec].value_name = names; + env->value_name = names; fpart = scheme_expand_expr_lift_to_let(code, env, erec, drec); code = cons(fpart, scheme_null); @@ -3520,7 +3564,7 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem Scheme_Object *form, *l, *fn, *vec, *dummy; Scheme_Comp_Env *env; - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN_FOR_SYNTAX(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN_FOR_SYNTAX(in_env->observer); form = orig_form; @@ -3529,7 +3573,7 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem (void)check_form(form, form); - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(in_env->observer); scheme_prepare_exp_env(in_env->genv); scheme_prepare_compile_env(in_env->genv->exp_env); @@ -3541,6 +3585,8 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem } else env = scheme_new_expand_env(in_env->genv->exp_env, in_env->insp, NULL, 0); + env->observer = in_env->observer; + if (rec[drec].comp) dummy = scheme_make_environment_dummy(in_env); else @@ -3576,7 +3622,7 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem break; } else { /* We have lifts: */ - SCHEME_EXPAND_OBSERVE_MODULE_LIFT_LOOP(rec[drec].observer, l); + SCHEME_EXPAND_OBSERVE_MODULE_LIFT_LOOP(env->observer, l); } } @@ -3699,7 +3745,7 @@ static void *eval_letmacro_rhs_k(void) void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object *a, Scheme_Env *exp_env, Scheme_Object *insp, - Scheme_Compile_Expand_Info *rec, int drec, + Scheme_Compile_Expand_Info *rec, int drec, Scheme_Object *observer, Scheme_Comp_Env *stx_env, Scheme_Comp_Env *rhs_env, int *_pos, Scheme_Object *rename_rib, int replace_value) @@ -3713,11 +3759,12 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object Scheme_Compile_Expand_Info mrec; eenv = scheme_new_comp_env(exp_env, insp, NULL, 0); + eenv->observer = observer; /* First expand for expansion-observation */ if (!rec[drec].comp) { scheme_init_expand_recs(rec, drec, &mrec, 1); - SCHEME_EXPAND_OBSERVE_ENTER_BIND(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_ENTER_BIND(eenv->observer); a = scheme_expand_expr_lift_to_let(a, eenv, &mrec, 0); } @@ -3726,13 +3773,19 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object mrec.dont_mark_local_use = 0; mrec.resolve_module_ids = 1; mrec.substitute_bindings = 1; - mrec.value_name = NULL; - mrec.observer = NULL; mrec.pre_unwrapped = 0; mrec.testing_constantness = 0; mrec.env_already = 0; mrec.comp_flags = rec[drec].comp_flags; + if (SCHEME_STX_PAIRP(names)) { + l = SCHEME_STX_CDR(names); + if (SCHEME_STX_NULLP(l)) { + l = SCHEME_STX_CAR(names); + eenv->value_name = SCHEME_STX_VAL(l); + } + } + a = scheme_compile_expr_lift_to_let(a, eenv, &mrec, 0); a = scheme_letrec_check_expr(a); @@ -3758,7 +3811,7 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object but it's not likely that a let-syntax-bound macro is going to run lots of times, so JITting is probably not worth it. */ - SCHEME_EXPAND_OBSERVE_NEXT(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(eenv->observer); a_expr = a; a = eval_letmacro_rhs(a_expr, rhs_env, @@ -3825,7 +3878,7 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object scheme_merge_undefineds(eenv, rhs_env); - SCHEME_EXPAND_OBSERVE_EXIT_BIND(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_EXIT_BIND(observer); } static Scheme_Object * @@ -3834,7 +3887,7 @@ do_letrec_syntaxes(const char *where, Scheme_Compile_Info *rec, int drec) { Scheme_Object *forms, *form, *bindings, *var_bindings, *body, *v, *scope; - Scheme_Object *names_to_disappear; + Scheme_Object *names_to_disappear, *orig_vname; Scheme_Comp_Env *stx_env, *var_env, *rhs_env; int cnt, stx_cnt, var_cnt, i, j, depth, saw_var, env_already, restore; DupCheckRecord r; @@ -3856,6 +3909,8 @@ do_letrec_syntaxes(const char *where, scheme_wrong_syntax(NULL, NULL, forms, NULL); body = scheme_datum_to_syntax(form, forms, forms, 0, 0); + orig_vname = origenv->value_name; + if (env_already) { stx_env = origenv; scope = NULL; @@ -4006,9 +4061,9 @@ do_letrec_syntaxes(const char *where, } } - SCHEME_EXPAND_OBSERVE_LETREC_SYNTAXES_RENAMES(rec[drec].observer, bindings, var_bindings, body); + SCHEME_EXPAND_OBSERVE_LETREC_SYNTAXES_RENAMES(stx_env->observer, bindings, var_bindings, body); - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(stx_env->observer); scheme_prepare_exp_env(stx_env->genv); scheme_prepare_compile_env(stx_env->genv->exp_env); @@ -4018,7 +4073,7 @@ do_letrec_syntaxes(const char *where, for (v = bindings; SCHEME_STX_PAIRP(v); v = SCHEME_STX_CDR(v)) { Scheme_Object *a, *names; - SCHEME_EXPAND_OBSERVE_NEXT(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(stx_env->observer); a = SCHEME_STX_CAR(v); names = SCHEME_STX_CAR(a); @@ -4028,13 +4083,13 @@ do_letrec_syntaxes(const char *where, scheme_bind_syntaxes(where, names, a, stx_env->genv->exp_env, stx_env->insp, - rec, drec, + rec, drec, stx_env->observer, stx_env, rhs_env, &i, NULL, 1); } } - SCHEME_EXPAND_OBSERVE_NEXT_GROUP(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT_GROUP(stx_env->observer); if (!env_already && names_to_disappear) { /* Need to add renaming for disappeared bindings. If they @@ -4069,9 +4124,9 @@ do_letrec_syntaxes(const char *where, if (!var_env) { var_env = stx_env; + v = scheme_check_name_property(forms, orig_vname); + var_env->value_name = v; if (rec[drec].comp) { - v = scheme_check_name_property(forms, rec[drec].value_name); - rec[drec].value_name = v; if (env_already) v = compile_list(body, var_env, rec, drec); else @@ -4097,9 +4152,10 @@ do_letrec_syntaxes(const char *where, v = scheme_stx_taint_rearm(v, orig_forms); if (!restore) { - SCHEME_EXPAND_OBSERVE_TAG(rec[drec].observer,v); + SCHEME_EXPAND_OBSERVE_TAG(stx_env->observer,v); } } + var_env->value_name = NULL; } else { /* Construct letrec-values expression: */ v = cons(letrec_values_symbol, cons(var_bindings, body)); @@ -4120,7 +4176,7 @@ do_letrec_syntaxes(const char *where, rec[drec].env_already = 1; } - SCHEME_EXPAND_OBSERVE_PRIM_LETREC_VALUES(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_LETREC_VALUES(stx_env->observer); v = do_let_expand(v, stx_env, rec, drec, "letrec-values", 1, 1, var_env); if (restore) { @@ -4132,7 +4188,7 @@ do_letrec_syntaxes(const char *where, v = cons(formname, cons(bindings, v)); v = scheme_datum_to_syntax(v, orig_forms, scheme_sys_wraps(origenv), 0, 2); } else { - SCHEME_EXPAND_OBSERVE_TAG(rec[drec].observer,v); + SCHEME_EXPAND_OBSERVE_TAG(stx_env->observer,v); } } } @@ -4154,7 +4210,7 @@ letrec_syntaxes_syntax(Scheme_Object *form, Scheme_Comp_Env *env, static Scheme_Object * letrec_syntaxes_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_LETREC_SYNTAXES_VALUES(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_LETREC_SYNTAXES_VALUES(env->observer); return do_letrec_syntaxes("letrec-syntaxes+values", form, env, erec, drec); } @@ -4378,15 +4434,14 @@ inner_compile_list(Scheme_Object *form, Scheme_Comp_Env *env, int i; Scheme_Object *c, *p, *comp_first, *comp_last, *name, *first, *rest; - name = rec[drec].value_name; + name = env->value_name; scheme_compile_rec_done_local(rec, drec); if (len <= 5) recs = quick; else - recs = MALLOC_N_RT(Scheme_Compile_Info, len); + recs = MALLOC_N_ATOMIC(Scheme_Compile_Info, len); scheme_init_compile_recs(rec, drec, recs, len); - recs[len - 1].value_name = name; comp_first = comp_last = NULL; @@ -4394,8 +4449,12 @@ inner_compile_list(Scheme_Object *form, Scheme_Comp_Env *env, first = SCHEME_STX_CAR(rest); rest = SCHEME_STX_CDR(rest); + if (SCHEME_STX_NULLP(rest)) + env->value_name = name; + c = compile_expand_expr(first, env, recs, i, !i && start_app_position); + env->value_name = NULL; p = scheme_make_pair(c, scheme_null); if (comp_last) @@ -4431,7 +4490,9 @@ static Scheme_Object *compile_application(Scheme_Object *form, Scheme_Comp_Env * if (len < 0) scheme_wrong_syntax(scheme_application_stx_string, NULL, form, NULL); - + + env->value_name = NULL; + scheme_compile_rec_done_local(rec, drec); form = inner_compile_list(form, scheme_no_defines(env), rec, drec, 1); @@ -4500,7 +4561,7 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, Scheme_Expand_Info erec1; Scheme_Env *menv = NULL; - SCHEME_EXPAND_OBSERVE_ENTER_CHECK(rec[drec].observer, first); + SCHEME_EXPAND_OBSERVE_ENTER_CHECK(env->observer, first); while (1) { *current_val = NULL; @@ -4513,7 +4574,7 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, } if (!SCHEME_STX_SYMBOLP(name)) { - SCHEME_EXPAND_OBSERVE_EXIT_CHECK(rec[drec].observer, first); + SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); return first; } @@ -4541,7 +4602,7 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, if (!val) { first = install_alt_from_rename(first, alt_first); - SCHEME_EXPAND_OBSERVE_EXIT_CHECK(rec[drec].observer, first); + SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); return first; } else if (SAME_TYPE(SCHEME_TYPE(val), scheme_macro_type)) { if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(val), @@ -4560,8 +4621,11 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, alt_first = NULL; scheme_init_expand_recs(rec, drec, &erec1, 1); erec1.depth = 1; - erec1.value_name = (keep_name ? rec[drec].value_name : scheme_false); + name = env->value_name; + if (!keep_name) + env->value_name = name; first = scheme_expand_expr(first, env, &erec1, 0); + env->value_name = name; break; /* break to outer loop */ } } else { @@ -4572,7 +4636,7 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, } } else { first = install_alt_from_rename(first, alt_first); - SCHEME_EXPAND_OBSERVE_EXIT_CHECK(rec[drec].observer, first); + SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); return first; } } @@ -4598,7 +4662,7 @@ compile_expand_macro_app(Scheme_Object *name, Scheme_Env *menv, Scheme_Object *m } } - boundname = rec[drec].value_name; + boundname = env->value_name; if (!boundname) boundname = scheme_false; @@ -4659,11 +4723,8 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Thread *p = scheme_current_thread; Scheme_Compile_Expand_Info *recx; - recx = MALLOC_ONE_RT(Scheme_Compile_Expand_Info); + recx = MALLOC_ONE_ATOMIC(Scheme_Compile_Expand_Info); memcpy(recx, rec + drec, sizeof(Scheme_Compile_Expand_Info)); -#ifdef MZTAG_REQUIRED - recx->type = scheme_rt_compile_info; -#endif p->ku.k.p1 = (void *)form; p->ku.k.p2 = (void *)env; @@ -4689,7 +4750,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, if (rec[drec].comp) { scheme_default_compile_rec(rec, drec); } else { - SCHEME_EXPAND_OBSERVE_VISIT(rec[drec].observer,form); + SCHEME_EXPAND_OBSERVE_VISIT(env->observer,form); } if (SAME_TYPE(SCHEME_TYPE(SCHEME_STX_VAL(form)), scheme_expanded_syntax_type)) { @@ -4746,7 +4807,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, &bind_id, &need_macro_scope, &inline_variant); - SCHEME_EXPAND_OBSERVE_RESOLVE(rec[drec].observer,find_name); + SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer,find_name); if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { @@ -4781,10 +4842,10 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } else { if (SAME_TYPE(SCHEME_TYPE(var), scheme_syntax_compiler_type)) { if (var == stop_expander) { - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(rec[drec].observer,form); - SCHEME_EXPAND_OBSERVE_PRIM_STOP(rec[drec].observer); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(rec[drec].observer,form); - SCHEME_EXPAND_OBSERVE_RETURN(rec[drec].observer,form); + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer,form); + SCHEME_EXPAND_OBSERVE_PRIM_STOP(env->observer); + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer,form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer,form); return form; } else { scheme_wrong_syntax(NULL, NULL, form, "bad syntax"); @@ -4818,14 +4879,14 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, else return var; } else { - SCHEME_EXPAND_OBSERVE_VARIABLE(rec[drec].observer, form, find_name); + SCHEME_EXPAND_OBSERVE_VARIABLE(env->observer, form, find_name); if (bind_id && rec[drec].substitute_bindings) find_name = bind_id; if (protected) { /* Add a property to indicate that the name is protected */ find_name = scheme_stx_property(find_name, protected_symbol, scheme_true); } - SCHEME_EXPAND_OBSERVE_RETURN(rec[drec].observer, find_name); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, find_name); return find_name; /* which is usually == form */ } } @@ -4874,7 +4935,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, NULL, &need_macro_scope, NULL); - SCHEME_EXPAND_OBSERVE_RESOLVE(rec[drec].observer, find_name); + SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer, find_name); if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), @@ -4912,10 +4973,10 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } else { Scheme_Syntax_Expander *f; f = (Scheme_Syntax_Expander *)SCHEME_SYNTAX_EXP(var); - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, form); form = f(form, env, rec, drec); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(rec[drec].observer, form); - SCHEME_EXPAND_OBSERVE_RETURN(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer, form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); return form; } } @@ -4971,7 +5032,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, NULL, &need_macro_scope, NULL); - SCHEME_EXPAND_OBSERVE_RESOLVE(rec[drec].observer, find_name); + SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer, find_name); if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { @@ -5002,12 +5063,12 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, || SAME_TYPE(SCHEME_TYPE(var), scheme_syntax_compiler_type))) { if (SAME_OBJ(var, stop_expander)) { /* Return original: */ - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(rec[drec].observer, form); - SCHEME_EXPAND_OBSERVE_PRIM_STOP(rec[drec].observer); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(rec[drec].observer, form); - SCHEME_EXPAND_OBSERVE_RETURN(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, form); + SCHEME_EXPAND_OBSERVE_PRIM_STOP(env->observer); + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer, form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); return form; - } else if (rec[drec].comp && SAME_OBJ(var, normal) && !rec[drec].observer) { + } else if (rec[drec].comp && SAME_OBJ(var, normal) && !env->observer) { /* Skip creation of intermediate form */ Scheme_Syntax *f; rec[drec].pre_unwrapped = 1; @@ -5026,7 +5087,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } else { name = scheme_stx_taint_disarm(form, NULL); form = scheme_datum_to_syntax(scheme_make_pair(stx, name), form, form, 0, 2); - SCHEME_EXPAND_OBSERVE_TAG(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_TAG(env->observer, form); } if (SAME_TYPE(SCHEME_TYPE(var), scheme_syntax_compiler_type)) { @@ -5037,10 +5098,10 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } else { Scheme_Syntax_Expander *f; f = (Scheme_Syntax_Expander *)SCHEME_SYNTAX_EXP(var); - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, form); form = f(form, env, rec, drec); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(rec[drec].observer, form); - SCHEME_EXPAND_OBSERVE_RETURN(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer, form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); return form; } } else { @@ -5085,11 +5146,11 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, macro: if (!rec[drec].comp && !rec[drec].depth) { - SCHEME_EXPAND_OBSERVE_RETURN(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); return form; /* We've gone as deep as requested */ } - SCHEME_EXPAND_OBSERVE_ENTER_MACRO(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_MACRO(env->observer, form); if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), scheme_frame_to_expansion_context_symbol(env->flags))) { form = compile_expand_macro_app(name, menv, var, form, env, rec, drec, need_macro_scope); @@ -5101,7 +5162,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } } else form = adjust_for_other_context(form, var, env); - SCHEME_EXPAND_OBSERVE_EXIT_MACRO(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_MACRO(env->observer, form); if (rec[drec].comp) goto top; @@ -5111,7 +5172,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, if (rec[drec].depth) goto top; else { - SCHEME_EXPAND_OBSERVE_RETURN(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); return form; } } @@ -5155,7 +5216,7 @@ static Scheme_Object * compile_expand_app(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Compile_Expand_Info *rec, int drec) { - Scheme_Object *form, *naya, *forms; + Scheme_Object *form, *naya, *forms, *orig_vname = env->value_name; int tsc; forms = scheme_stx_taint_disarm(orig_form, NULL); @@ -5185,7 +5246,7 @@ compile_expand_app(Scheme_Object *orig_form, Scheme_Comp_Env *env, if (rec[drec].comp) return compile_application(form, env, rec, drec); else { - rec[drec].value_name = scheme_false; + env->value_name = NULL; naya = expand_list(form, scheme_no_defines(env), rec, drec); /* naya will be prefixed and returned... */ } @@ -5193,9 +5254,14 @@ compile_expand_app(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Object *name, *origname, *gval, *orig_rest_form, *rest_form; name = SCHEME_STX_CAR(form); origname = name; + + gval = env->value_name; + env->value_name = NULL; name = scheme_check_immediate_macro(name, env, rec, drec, &gval, 0); + env->value_name = gval; + /* look for ((lambda (x ...) ....) ....) or ((lambda x ....) ....) */ if (SAME_OBJ(gval, scheme_lambda_syntax)) { Scheme_Object *argsnbody, *d_name; @@ -5271,6 +5337,8 @@ compile_expand_app(Scheme_Object *orig_form, Scheme_Comp_Env *env, body = scheme_syntax_taint_rearm(body, orig_form); + env->value_name = orig_vname; + return compile_expand_expr(body, env, rec, drec, 0); } else { #if 0 @@ -5336,6 +5404,7 @@ compile_expand_app(Scheme_Object *orig_form, Scheme_Comp_Env *env, scheme_null), icons(second, scheme_null))); form = scheme_datum_to_syntax(name, forms, scheme_sys_wraps(env), 0, 2); + env->value_name = orig_vname; return compile_expand_expr(form, env, rec, drec, 0); } if (!SAME_OBJ(second, orig_second)) { @@ -5359,10 +5428,10 @@ compile_expand_app(Scheme_Object *orig_form, Scheme_Comp_Env *env, || NOT_SAME_OBJ(rest_form, orig_rest_form)) { form = scheme_datum_to_syntax(scheme_make_pair(name, rest_form), forms, forms, 0, 2); } - + return compile_application(form, env, rec, drec); } else { - rec[drec].value_name = scheme_false; + env->value_name = NULL; naya = expand_list(form, scheme_no_defines(env), rec, drec); /* naya will be prefixed returned... */ } @@ -5388,7 +5457,7 @@ app_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, static Scheme_Object * app_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_APP(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_APP(env->observer); return compile_expand_app(form, env, erec, drec); } @@ -5420,7 +5489,7 @@ datum_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info { Scheme_Object *rest, *v, *form; - SCHEME_EXPAND_OBSERVE_PRIM_DATUM(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_DATUM(env->observer); form = scheme_stx_taint_disarm(orig_form, NULL); @@ -5563,7 +5632,7 @@ top_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, Scheme_Object *c; int need_bound_check = 0; - SCHEME_EXPAND_OBSERVE_PRIM_TOP(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_TOP(env->observer); c = check_top(form, env, erec, drec, &need_bound_check); if (env->genv->module) @@ -5682,11 +5751,8 @@ compile_expand_expr_lift_to_let(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Thread *p = scheme_current_thread; Scheme_Compile_Expand_Info *recx; - recx = MALLOC_ONE_RT(Scheme_Compile_Expand_Info); + recx = MALLOC_ONE_ATOMIC(Scheme_Compile_Expand_Info); memcpy(recx, rec + drec, sizeof(Scheme_Compile_Expand_Info)); -#ifdef MZTAG_REQUIRED - recx->type = scheme_rt_compile_info; -#endif p->ku.k.p1 = (void *)form; p->ku.k.p2 = (void *)env; @@ -5735,7 +5801,7 @@ compile_expand_expr_lift_to_let(Scheme_Object *form, Scheme_Comp_Env *env, } else o = form; form = scheme_add_lifts_as_let(o, l, env, orig_form, rec[drec].comp); - SCHEME_EXPAND_OBSERVE_LETLIFT_LOOP(rec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_LETLIFT_LOOP(env->observer, form); form = compile_expand_expr_lift_to_let(form, env, recs, 1); if (rec[drec].comp) scheme_merge_compile_recs(rec, drec, recs, 2); @@ -5793,7 +5859,7 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, It is espcailly ugly because we have to expand macros before deciding what we have. */ { - Scheme_Object *first, *orig = forms, *pre_exprs = scheme_null, *old; + Scheme_Object *first, *orig = forms, *pre_exprs = scheme_null, *old, *orig_vname = env->value_name; Scheme_Object *rib, *ectx, *frame_scopes; Scheme_Compile_Info recs[2]; DupCheckRecord r; @@ -5801,7 +5867,7 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (rec[drec].comp) { scheme_default_compile_rec(rec, drec); } else { - SCHEME_EXPAND_OBSERVE_ENTER_BLOCK(rec[drec].observer, forms); + SCHEME_EXPAND_OBSERVE_ENTER_BLOCK(env->observer, forms); } if (SCHEME_STX_NULLP(forms)) { @@ -5809,9 +5875,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, scheme_compile_rec_done_local(rec, drec); return scheme_null; } else { - SCHEME_EXPAND_OBSERVE_BLOCK_TO_LIST(rec[drec].observer, forms); - SCHEME_EXPAND_OBSERVE_ENTER_LIST(rec[drec].observer, forms); - SCHEME_EXPAND_OBSERVE_EXIT_LIST(rec[drec].observer, forms); + SCHEME_EXPAND_OBSERVE_BLOCK_TO_LIST(env->observer, forms); + SCHEME_EXPAND_OBSERVE_ENTER_LIST(env->observer, forms); + SCHEME_EXPAND_OBSERVE_EXIT_LIST(env->observer, forms); return forms; } } @@ -5836,11 +5902,11 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, old = forms; forms = add_scope_at_arbitrary_phase(forms, rib); - SCHEME_EXPAND_OBSERVE_BLOCK_RENAMES(rec[drec].observer, forms, old); + SCHEME_EXPAND_OBSERVE_BLOCK_RENAMES(env->observer, forms, old); try_again: - SCHEME_EXPAND_OBSERVE_NEXT(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); if (!SCHEME_STX_PAIRP(forms)) { scheme_wrong_syntax(scheme_begin_stx_string, NULL, beginify(env, forms), "bad syntax"); @@ -5865,7 +5931,7 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, /* Inline content */ Scheme_Object *orig_forms = forms; - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(env->observer); /* FIXME: Redundant with check done by scheme_flatten_begin below? */ if (scheme_stx_proper_list_length(first) < 0) @@ -5879,13 +5945,13 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, attached to this begin should apply to the ultimate last thing in the block. */ Scheme_Object *v; - v = scheme_check_name_property(first, rec[drec].value_name); - rec[drec].value_name = v; + v = scheme_check_name_property(first, env->value_name); + env->value_name = v; } forms = scheme_flatten_begin(first, forms); - SCHEME_EXPAND_OBSERVE_SPLICE(rec[drec].observer, forms); + SCHEME_EXPAND_OBSERVE_SPLICE(env->observer, forms); if (SCHEME_STX_NULLP(forms)) { if (!SCHEME_PAIRP(pre_exprs)) { @@ -5952,9 +6018,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, v = SCHEME_STX_CDR(first); if (is_val) { - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(env->observer); } else { - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(env->observer); } if (!SCHEME_STX_PAIRP(v)) @@ -5984,7 +6050,7 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, var = SCHEME_STX_CAR(first); v = scheme_stx_track(v, first, var); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(rec[drec].observer,v); + SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer,v); link = scheme_make_pair(v, scheme_null); if (is_val) { @@ -6052,13 +6118,14 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (!is_val) { /* Evaluate and bind syntaxes */ - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); scheme_prepare_exp_env(new_env->genv); scheme_prepare_compile_env(new_env->genv->exp_env); pos = 0; scheme_bind_syntaxes("local syntax definition", names, expr, - new_env->genv->exp_env, new_env->insp, rec, drec, + new_env->genv->exp_env, new_env->insp, + rec, drec, new_env->observer, new_env, new_env, &pos, rib, 1); } @@ -6074,7 +6141,7 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (!SCHEME_STX_NULLP(result)) { first = SCHEME_STX_CAR(result); first = scheme_datum_to_syntax(first, forms, forms, 0, 0); - SCHEME_EXPAND_OBSERVE_NEXT(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); is_last = SCHEME_STX_NULLP(SCHEME_STX_CDR(result)); first = scheme_check_immediate_macro(first, env, rec, drec, &gval, is_last); more = 1; @@ -6083,9 +6150,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (SAME_OBJ(gval, scheme_begin_syntax)) { /* Inline content */ result = SCHEME_STX_CDR(result); - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(env->observer); result = scheme_flatten_begin(first, result); - SCHEME_EXPAND_OBSERVE_SPLICE(rec[drec].observer,result); + SCHEME_EXPAND_OBSERVE_SPLICE(env->observer,result); goto define_try_again; } else if (mixed) { /* accumulate expr for either sequence after definitions @@ -6152,7 +6219,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, rec[drec].env_already = (mixed ? 2 : 1); if (rec[drec].comp) { - result = scheme_compile_expr(result, scheme_no_defines(env), rec, drec); + env = scheme_no_defines(env); + env->value_name = orig_vname; + result = scheme_compile_expr(result, env, rec, drec); return scheme_make_pair(result, scheme_null); } else { if (!mixed && ((rec[drec].depth == -2) || (rec[drec].depth > 0))) { @@ -6162,9 +6231,11 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (rec[drec].depth > 0) --rec[drec].depth; if (rec[drec].depth) { - SCHEME_EXPAND_OBSERVE_BLOCK_TO_LETREC(rec[drec].observer, + SCHEME_EXPAND_OBSERVE_BLOCK_TO_LETREC(env->observer, scheme_make_pair(result, scheme_null)); - result = scheme_expand_expr(result, scheme_no_defines(env), rec, drec); + env = scheme_no_defines(env); + env->value_name = orig_vname; + result = scheme_expand_expr(result, env, rec, drec); } result = scheme_make_pair(result, scheme_null); return scheme_datum_to_syntax(result, forms, forms, 0, 0); @@ -6178,9 +6249,8 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, env = scheme_no_defines(env); if (rec[drec].comp) { - Scheme_Object *vname, *rest; + Scheme_Object *rest; - vname = rec[drec].value_name; scheme_compile_rec_done_local(rec, drec); scheme_init_compile_recs(rec, drec, recs, 2); @@ -6191,28 +6261,29 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, rest = SCHEME_CDR(pre_exprs); } - if (SCHEME_STX_NULLP(rest)) - recs[0].value_name = vname; - else - recs[1].value_name = vname; - rest = scheme_datum_to_syntax(rest, orig, orig, 0, 0); + if (SCHEME_STX_NULLP(rest)) + env->value_name = orig_vname; + else + env->value_name = NULL; + first = scheme_compile_expr(first, env, recs, 0); + if (!SCHEME_STX_NULLP(rest)) + env->value_name = orig_vname; + else + env->value_name = NULL; + forms = compile_list(rest, env, recs, 1); scheme_merge_compile_recs(rec, drec, recs, 2); return scheme_make_pair(first, forms); } else { - Scheme_Object *newforms, *vname; + Scheme_Object *newforms; - vname = rec[drec].value_name; - rec[drec].value_name = scheme_false; scheme_init_expand_recs(rec, drec, recs, 2); - recs[0].value_name = vname; - if (SCHEME_PAIRP(pre_exprs)) newforms = pre_exprs; else { @@ -6225,7 +6296,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (scheme_stx_proper_list_length(forms) < 0) scheme_wrong_syntax(scheme_begin_stx_string, NULL, beginify(env, forms), "bad syntax"); - SCHEME_EXPAND_OBSERVE_BLOCK_TO_LIST(rec[drec].observer, forms); + env->value_name = orig_vname; + + SCHEME_EXPAND_OBSERVE_BLOCK_TO_LIST(env->observer, forms); forms = expand_list(forms, env, recs, 0); return forms; } @@ -6260,12 +6333,12 @@ expand_stratified_block(Scheme_Object *forms, Scheme_Comp_Env *env, Scheme_Expan static Scheme_Object *expand_list(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - Scheme_Object *first = NULL, *last = NULL, *fm; + Scheme_Object *first = NULL, *last = NULL, *fm, *vname; - SCHEME_EXPAND_OBSERVE_ENTER_LIST(erec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_LIST(env->observer, form); if (SCHEME_STX_NULLP(form)) { - SCHEME_EXPAND_OBSERVE_EXIT_LIST(erec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_LIST(env->observer, form); return scheme_null; } @@ -6276,16 +6349,17 @@ static Scheme_Object *expand_list(Scheme_Object *form, Scheme_Comp_Env *env, } fm = form; + vname = env->value_name; while (SCHEME_STX_PAIRP(fm)) { Scheme_Object *r, *p; Scheme_Expand_Info erec1; - SCHEME_EXPAND_OBSERVE_NEXT(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); p = SCHEME_STX_CDR(fm); scheme_init_expand_recs(erec, drec, &erec1, 1); - erec1.value_name = (SCHEME_STX_NULLP(p) ? erec[drec].value_name : scheme_false); + env->value_name = (SCHEME_STX_NULLP(p) ? vname : NULL); r = SCHEME_STX_CAR(fm); r = scheme_expand_expr(r, env, &erec1, 0); @@ -6296,11 +6370,13 @@ static Scheme_Object *expand_list(Scheme_Object *form, Scheme_Comp_Env *env, first = p; last = p; + env->value_name = NULL; + fm = SCHEME_STX_CDR(fm); } form = scheme_datum_to_syntax(first, form, form, 0, 0); - SCHEME_EXPAND_OBSERVE_EXIT_LIST(erec[drec].observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_LIST(env->observer, form); return form; } @@ -6340,7 +6416,7 @@ static Scheme_Object *stop_syntax(Scheme_Object *form, Scheme_Comp_Env *env, static Scheme_Object *stop_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_STOP(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_STOP(env->observer); return form; } diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 518331074b..72f5080e52 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -4150,8 +4150,6 @@ static void *compile_k(void) rec.dont_mark_local_use = 0; rec.resolve_module_ids = !writeable && !genv->module; rec.substitute_bindings = 1; - rec.value_name = scheme_false; - rec.observer = NULL; rec.pre_unwrapped = 0; rec.env_already = 0; rec.comp_flags = comp_flags; @@ -4652,6 +4650,8 @@ static void *expand_k(void) observer = scheme_get_expand_observe(); SCHEME_EXPAND_OBSERVE_START_EXPAND(observer); + env->observer = observer; + comp_flags = get_comp_flags(NULL); if (as_local < 0) { @@ -4668,8 +4668,6 @@ static void *expand_k(void) while (1) { erec1.comp = 0; erec1.depth = ((depth == -3) ? -2 : depth); - erec1.value_name = scheme_false; - erec1.observer = observer; erec1.pre_unwrapped = 0; erec1.env_already = 0; erec1.comp_flags = comp_flags; @@ -4709,13 +4707,13 @@ static void *expand_k(void) obj = scheme_add_lifts_as_let(obj, l, env, scheme_false, 0); else obj = add_lifts_as_begin(obj, l, env); - SCHEME_EXPAND_OBSERVE_LIFT_LOOP(erec1.observer,obj); + SCHEME_EXPAND_OBSERVE_LIFT_LOOP(env->observer, obj); if ((depth >= 0) || as_local) break; } else { if (as_local > 0) { obj = add_lifts_as_begin(obj, scheme_null, env); - SCHEME_EXPAND_OBSERVE_LIFT_LOOP(erec1.observer,obj); + SCHEME_EXPAND_OBSERVE_LIFT_LOOP(env->observer,obj); } break; } @@ -5301,6 +5299,8 @@ do_local_expand(const char *name, int for_stx, int catch_lifts, int for_expr, in } } + env->observer = observer; + if (local_scope) { /* Since we have an expression from local context, we need to remove the temporary scope... */ @@ -5336,15 +5336,16 @@ do_local_expand(const char *name, int for_stx, int catch_lifts, int for_expr, in } memset(drec, 0, sizeof(drec)); - drec[0].value_name = scheme_false; /* or scheme_current_thread->current_local_name ? */ drec[0].depth = -2; - drec[0].observer = observer; { int comp_flags; comp_flags = get_comp_flags(NULL); drec[0].comp_flags = comp_flags; } + if (!(env->flags & (SCHEME_TOPLEVEL_FRAME | SCHEME_MODULE_FRAME | SCHEME_MODULE_BEGIN_FRAME))) + env->value_name = scheme_current_thread->current_local_name; + xl = scheme_check_immediate_macro(l, env, drec, 0, &gval, 1); if (SAME_OBJ(xl, l) && !for_expr) { @@ -5830,6 +5831,7 @@ local_eval(int argc, Scheme_Object **argv) stx_env = scheme_new_compilation_frame(0, SCHEME_FOR_INTDEF | SCHEME_USE_SCOPES_TO_NEXT, rib, stx_env); scheme_add_local_syntax(cnt, stx_env); + env->observer = observer; /* Scope names */ if (scheme_current_thread->current_local_scope) @@ -5852,8 +5854,6 @@ local_eval(int argc, Scheme_Object **argv) Scheme_Compile_Expand_Info rec; rec.comp = 0; rec.depth = -1; - rec.value_name = scheme_false; - rec.observer = observer; rec.pre_unwrapped = 0; rec.env_already = 0; rec.substitute_bindings = 1; @@ -5872,7 +5872,8 @@ local_eval(int argc, Scheme_Object **argv) scheme_make_pair(rib, scheme_env_phase(stx_env->genv))); rn_names = scheme_named_map_1(NULL, revert_expr_scopes, rn_names, (Scheme_Object *)init_env); scheme_bind_syntaxes("local syntax definition", rn_names, expr, - stx_env->genv->exp_env, stx_env->insp, &rec, 0, + stx_env->genv->exp_env, stx_env->insp, + &rec, 0, stx_env->observer, stx_env, stx_env, &pos, rib, 1); } @@ -6097,7 +6098,7 @@ static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC GC_set_backpointer_object(pf->backpointer); #endif GC_mark_no_recur(gc, 1); - gcMARK(pf); + gcMARK2(pf, gc); pf = (Scheme_Prefix *)GC_resolve2(pf, gc); GC_retract_only_mark_stack_entry(pf, gc); GC_mark_no_recur(gc, 0); @@ -6132,7 +6133,6 @@ START_XFORM_SKIP; static void register_traversers(void) { - GC_REG_TRAV(scheme_rt_compile_info, mark_comp_info); GC_REG_TRAV(scheme_rt_saved_stack, mark_saved_stack); } diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 644e8da8af..f75649c190 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -1953,7 +1953,7 @@ scheme_apply_macro(Scheme_Object *name, Scheme_Env *menv, code = scheme_stx_taint_disarm(code, NULL); pre_code = code; - SCHEME_EXPAND_OBSERVE_MACRO_PRE_X(rec[drec].observer, code); + SCHEME_EXPAND_OBSERVE_MACRO_PRE_X(env->observer, code); { Scheme_Dynamic_State dyn_state; @@ -1976,7 +1976,7 @@ scheme_apply_macro(Scheme_Object *name, Scheme_Env *menv, scheme_pop_continuation_frame(&cframe); } - SCHEME_EXPAND_OBSERVE_MACRO_POST_X(rec[drec].observer, code, pre_code); + SCHEME_EXPAND_OBSERVE_MACRO_POST_X(env->observer, code, pre_code); if (!SCHEME_STXP(code)) { scheme_raise_exn(MZEXN_FAIL_CONTRACT, diff --git a/racket/src/racket/src/mkmark.rkt b/racket/src/racket/src/mkmark.rkt index 84b9164ab1..97ce186d5c 100644 --- a/racket/src/racket/src/mkmark.rkt +++ b/racket/src/racket/src/mkmark.rkt @@ -31,19 +31,23 @@ [(regexp-match re:close l) (error 'mkmark.rkt "unexpected close")] [else (cons l (loop))])))))] - [print-lines (lambda (l [skip-rx #f]) + [print-lines (lambda (l [skip-rx #f] [skip-alt-bracket #f]) (let loop ([l l] [skip? #f]) (cond [(null? l) (void)] [(and skip-rx (regexp-match? skip-rx (car l))) + (when skip-alt-bracket + (if skip? + (printf "#endif\n") + (printf "#ifdef ~a\n" skip-alt-bracket))) (loop (cdr l) (not skip?))] - [skip? + [(and skip? (not skip-alt-bracket)) (loop (cdr l) #t)] [(regexp-match? #rx"(START|END)_[A-Z_]+_ONLY;" (car l)) (loop (cdr l) skip?)] [else (printf "~a\n" (car l)) - (loop (cdr l) #f)])))]) + (loop (cdr l) skip?)])))]) (let ([prefix (read-lines re:mark)] [mark (read-lines re:size-or-more)] [fixup (if (regexp-match-peek re:fixup-start (current-input-port)) @@ -52,13 +56,26 @@ (read-lines re:size)) null)] [size (read-lines re:close)]) + + (define (print-size size) + (printf "# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS\n") + (printf " return 0;\n") + (printf "# else\n") + (printf " return\n") + (print-lines size) + (printf "# endif\n")) + (printf "static int ~a_SIZE(void *p, struct NewGC *gc) {\n" name) + (printf "#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS\n") (print-lines prefix) - (printf " return\n") (print-lines size) + (printf "#else\n") + (printf " return 0;\n") + (printf "#endif\n") (printf "}\n\n") (printf "static int ~a_MARK(void *p, struct NewGC *gc) {\n" name) + (printf "#ifndef GC_NO_MARK_PROCEDURE_NEEDED\n") (print-lines prefix) (print-lines (map (lambda (s) (regexp-replace* @@ -70,11 +87,12 @@ "")) mark) #rx"FIXUP_ONLY") - (printf " return\n") - (print-lines size) + (print-size size) + (printf "#endif\n") (printf "}\n\n") (printf "static int ~a_FIXUP(void *p, struct NewGC *gc) {\n" name) + (printf "#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED\n") (print-lines prefix) (print-lines (map (lambda (s) (regexp-replace* @@ -88,8 +106,8 @@ mark fixup)) #rx"MARK_ONLY") - (printf " return\n") - (print-lines size) + (print-size size) + (printf "#endif\n") (printf "}\n\n") (printf "#define ~a_IS_ATOMIC ~a\n" diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index b1081f425c..41c8e0177d 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7041,7 +7041,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, LOG_EXPAND_DECLS; if (!rec[drec].comp) { - SCHEME_EXPAND_OBSERVE_PRIM_MODULE(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_MODULE(env->observer); if (rec[drec].depth > 0) rec[drec].depth++; } @@ -7205,7 +7205,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, m->super_bxs_info = super_bxs_info; } - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(rec[drec].observer); + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); /* load the module for the initial require */ if (iidx) { @@ -7291,6 +7291,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, else benv = scheme_new_expand_env(menv, env->insp, frame_scopes, SCHEME_MODULE_BEGIN_FRAME | SCHEME_KEEP_SCOPES_FRAME); + benv->observer = env->observer; } /* If fm isn't a single expression, it certainly needs a @@ -7308,7 +7309,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_datum_to_syntax(fm, form, mb_ctx, 0, 2); if (check_mb) { - SCHEME_EXPAND_OBSERVE_TAG(rec[drec].observer, fm); + SCHEME_EXPAND_OBSERVE_TAG(env->observer, fm); } fm = scheme_stx_property(fm, module_name_symbol, scheme_resolved_module_path_value(rmp)); @@ -7321,7 +7322,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_stx_add_module_frame_context(fm, rn_set); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(rec[drec].observer, fm); + SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer, fm); if (!check_mb) { fm = scheme_check_immediate_macro(fm, benv, rec, drec, &mbval, 1); @@ -7334,7 +7335,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_datum_to_syntax(fm, form, mb_ctx, 0, 2); fm = scheme_stx_property(fm, module_name_symbol, scheme_resolved_module_path_value(rmp)); - SCHEME_EXPAND_OBSERVE_TAG(rec[drec].observer, fm); + SCHEME_EXPAND_OBSERVE_TAG(env->observer, fm); check_mb = 1; } @@ -7451,7 +7452,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, LOG_END_EXPAND(m); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(rec[drec].observer, fm); + SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer, fm); return fm; } @@ -8178,7 +8179,7 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env scoped identifiers for definitions. */ form = introduce_to_module_context(form, rn_set); - observer = rec[drec].observer; + observer = env->observer; SCHEME_EXPAND_OBSERVE_RENAME_ONE(observer, form); _num_phases = MALLOC_ONE_ATOMIC(int); @@ -8226,8 +8227,6 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env crec.dont_mark_local_use = 0; crec.resolve_module_ids = 0; crec.substitute_bindings = 1; - crec.value_name = scheme_false; - crec.observer = NULL; crec.pre_unwrapped = 0; crec.env_already = 0; crec.comp_flags = rec[drec].comp_flags; @@ -8692,20 +8691,14 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ void **args; if (rec) { - recx = MALLOC_ONE_RT(Scheme_Compile_Expand_Info); + recx = MALLOC_ONE_ATOMIC(Scheme_Compile_Expand_Info); memcpy(recx, rec + drec, sizeof(Scheme_Compile_Expand_Info)); -#ifdef MZTAG_REQUIRED - recx->type = scheme_rt_compile_info; -#endif } else recx = NULL; if (erec) { - erecx = MALLOC_ONE_RT(Scheme_Compile_Expand_Info); + erecx = MALLOC_ONE_ATOMIC(Scheme_Compile_Expand_Info); memcpy(erecx, erec + derec, sizeof(Scheme_Compile_Expand_Info)); -#ifdef MZTAG_REQUIRED - erecx->type = scheme_rt_compile_info; -#endif } else erecx = NULL; @@ -8813,11 +8806,8 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ /* For syntax-local-context, etc., in a d-s RHS: */ rhs_env = scheme_new_comp_env(env->genv, env->insp, NULL, SCHEME_TOPLEVEL_FRAME); - if (erec) { - observer = erec[derec].observer; - } else { - observer = NULL; - } + observer = env->observer; + rhs_env->observer = observer; maybe_has_lifts = 0; lift_ctx = scheme_generate_lifts_key(); @@ -8864,8 +8854,6 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ Scheme_Expand_Info erec1; erec1.comp = 0; erec1.depth = -1; - erec1.value_name = scheme_false; - erec1.observer = observer; erec1.pre_unwrapped = 0; erec1.substitute_bindings = 1; erec1.env_already = 0; @@ -9107,8 +9095,6 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ mrec.dont_mark_local_use = 0; mrec.resolve_module_ids = 0; mrec.substitute_bindings = 1; - mrec.value_name = NULL; - mrec.observer = NULL; mrec.pre_unwrapped = 0; mrec.env_already = 0; mrec.comp_flags = rec[drec].comp_flags; @@ -9116,8 +9102,6 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ if (erec) { erec1.comp = 0; erec1.depth = -1; - erec1.value_name = boundname; - erec1.observer = observer; erec1.pre_unwrapped = 0; erec1.substitute_bindings = 1; erec1.env_already = 0; @@ -9151,9 +9135,14 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ } else { if (erec) { SCHEME_EXPAND_OBSERVE_PHASE_UP(observer); + eenv->value_name = boundname; + eenv->observer = xenv->observer; code = scheme_expand_expr_lift_to_let(code, eenv, &erec1, 0); } + eenv->value_name = boundname; + eenv->observer = NULL; m = scheme_compile_expr_lift_to_let(code, eenv, &mrec, 0); + eenv->value_name = NULL; } if (!for_stx) { @@ -9370,6 +9359,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ frame_scopes = scheme_module_context_frame_scopes(rn_set, xenv->scopes); cenv = scheme_new_comp_env(env->genv, env->insp, frame_scopes, SCHEME_TOPLEVEL_FRAME | SCHEME_KEEP_SCOPES_FRAME); + cenv->observer = env->observer; } lift_data = scheme_make_vector(3, NULL); @@ -9435,7 +9425,6 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ if (erec) { Scheme_Expand_Info erec1; scheme_init_expand_recs(erec, derec, &erec1, 1); - erec1.value_name = scheme_false; e = scheme_expand_expr(e, nenv, &erec1, 0); expanded_l = scheme_make_pair(e, expanded_l); } @@ -9444,7 +9433,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ Scheme_Compile_Info crec1; scheme_init_compile_recs(rec, drec, &crec1, 1); crec1.resolve_module_ids = 0; + nenv->observer = NULL; e = scheme_compile_expr(e, nenv, &crec1, 0); + nenv->observer = env->observer; } lifted_reqs = scheme_frame_get_require_lifts(cenv); @@ -9657,7 +9648,7 @@ static Scheme_Object *expand_all_provides(Scheme_Object *form, Scheme_Object *e, *ex, *fst; Scheme_Comp_Env *pcenv; - observer = rec[drec].observer; + observer = cenv->observer; saved_provides = scheme_reverse(bxs->saved_provides); while (!SCHEME_NULLP(saved_provides)) { @@ -9684,6 +9675,7 @@ static Scheme_Object *expand_all_provides(Scheme_Object *form, pcenv = scheme_new_comp_env(penv, penv->access_insp, NULL, SCHEME_TOPLEVEL_FRAME); else pcenv = scheme_new_expand_env(penv, penv->access_insp, NULL, SCHEME_TOPLEVEL_FRAME); + pcenv->observer = cenv->observer; } else { pcenv = cenv; } @@ -9728,10 +9720,10 @@ static Scheme_Object *expand_submodules(Scheme_Compile_Expand_Info *rec, int dre while (!SCHEME_NULLP(l)) { mod = SCHEME_CAR(l); - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(rec[drec].observer,SCHEME_CAR(mod)); + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, SCHEME_CAR(mod)); mod = do_module(SCHEME_CAR(mod), env, rec, drec, ancestry, env->genv->module->submodule_path, post, bxs, SCHEME_CDR(mod)); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(rec[drec].observer,mod); + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer,mod); mods = scheme_make_pair(mod, mods); @@ -9951,7 +9943,7 @@ module_begin_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_In static Scheme_Object * module_begin_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_MODULE_BEGIN(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_MODULE_BEGIN(env->observer); return do_module_begin(form, env, erec, drec); } @@ -10846,7 +10838,6 @@ static Scheme_Object *expand_provide(Scheme_Object *e, int at_phase, stop, xenv, 0); scheme_init_expand_recs(rec, drec, &erec1, 1); - erec1.value_name = scheme_false; erec1.depth = -1; p = scheme_current_thread; @@ -12597,7 +12588,7 @@ require_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *r static Scheme_Object * require_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_REQUIRE(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_REQUIRE(env->observer); return do_require(form, env, erec, drec); } @@ -12631,7 +12622,7 @@ provide_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *r static Scheme_Object * provide_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_PROVIDE(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_PROVIDE(env->observer); scheme_wrong_syntax(NULL, NULL, form, "not in module body"); return NULL; } @@ -12646,7 +12637,7 @@ declare_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *r static Scheme_Object * declare_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec, int drec) { - SCHEME_EXPAND_OBSERVE_PRIM_PROVIDE(erec[drec].observer); + SCHEME_EXPAND_OBSERVE_PRIM_PROVIDE(env->observer); scheme_wrong_syntax(NULL, NULL, form, "not in module body"); return NULL; } diff --git a/racket/src/racket/src/mzmark_compenv.inc b/racket/src/racket/src/mzmark_compenv.inc index b62c6324bf..ddcbeff3ba 100644 --- a/racket/src/racket/src/mzmark_compenv.inc +++ b/racket/src/racket/src/mzmark_compenv.inc @@ -1,11 +1,15 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_comp_env_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Comp_Env)); +#else + return 0; +#endif } static int mark_comp_env_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Comp_Env *e = (Scheme_Comp_Env *)p; gcMARK2(e->genv, gc); @@ -13,6 +17,8 @@ static int mark_comp_env_MARK(void *p, struct NewGC *gc) { gcMARK2(e->prefix, gc); gcMARK2(e->next, gc); gcMARK2(e->scopes, gc); + gcMARK2(e->value_name, gc); + gcMARK2(e->observer, gc); gcMARK2(e->binders, gc); gcMARK2(e->bindings, gc); gcMARK2(e->vals, gc); @@ -30,11 +36,17 @@ static int mark_comp_env_MARK(void *p, struct NewGC *gc) { gcMARK2(e->expand_result_adjust_arg, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Comp_Env)); +# endif +#endif } static int mark_comp_env_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Comp_Env *e = (Scheme_Comp_Env *)p; gcFIXUP2(e->genv, gc); @@ -42,6 +54,8 @@ static int mark_comp_env_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(e->prefix, gc); gcFIXUP2(e->next, gc); gcFIXUP2(e->scopes, gc); + gcFIXUP2(e->value_name, gc); + gcFIXUP2(e->observer, gc); gcFIXUP2(e->binders, gc); gcFIXUP2(e->bindings, gc); gcFIXUP2(e->vals, gc); @@ -59,8 +73,13 @@ static int mark_comp_env_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(e->expand_result_adjust_arg, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Comp_Env)); +# endif +#endif } #define mark_comp_env_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_eval.inc b/racket/src/racket/src/mzmark_eval.inc index c8f5fd6877..a8b65ad3ee 100644 --- a/racket/src/racket/src/mzmark_eval.inc +++ b/racket/src/racket/src/mzmark_eval.inc @@ -1,57 +1,43 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ -static int mark_comp_info_SIZE(void *p, struct NewGC *gc) { - return - gcBYTES_TO_WORDS(sizeof(Scheme_Compile_Info)); -} - -static int mark_comp_info_MARK(void *p, struct NewGC *gc) { - Scheme_Compile_Info *i = (Scheme_Compile_Info *)p; - - gcMARK2(i->value_name, gc); - gcMARK2(i->observer, gc); - - return - gcBYTES_TO_WORDS(sizeof(Scheme_Compile_Info)); -} - -static int mark_comp_info_FIXUP(void *p, struct NewGC *gc) { - Scheme_Compile_Info *i = (Scheme_Compile_Info *)p; - - gcFIXUP2(i->value_name, gc); - gcFIXUP2(i->observer, gc); - - return - gcBYTES_TO_WORDS(sizeof(Scheme_Compile_Info)); -} - -#define mark_comp_info_IS_ATOMIC 0 -#define mark_comp_info_IS_CONST_SIZE 1 - - static int mark_saved_stack_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Saved_Stack)); +#else + return 0; +#endif } static int mark_saved_stack_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Saved_Stack *saved = (Scheme_Saved_Stack *)p; gcMARK2(saved->prev, gc); gcMARK2(saved->runstack_start, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Saved_Stack)); +# endif +#endif } static int mark_saved_stack_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Saved_Stack *saved = (Scheme_Saved_Stack *)p; gcFIXUP2(saved->prev, gc); gcFIXUP2(saved->runstack_start, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Saved_Stack)); +# endif +#endif } #define mark_saved_stack_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_fun.inc b/racket/src/racket/src/mzmark_fun.inc index 8a14ce24f7..85356880c5 100644 --- a/racket/src/racket/src/mzmark_fun.inc +++ b/racket/src/racket/src/mzmark_fun.inc @@ -1,30 +1,45 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_closure_info_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Closure_Info)); +#else + return 0; +#endif } static int mark_closure_info_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Closure_Info *i = (Closure_Info *)p; gcMARK2(i->local_flags, gc); gcMARK2(i->base_closure_map, gc); gcMARK2(i->local_type_map, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Closure_Info)); +# endif +#endif } static int mark_closure_info_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Closure_Info *i = (Closure_Info *)p; gcFIXUP2(i->local_flags, gc); gcFIXUP2(i->base_closure_map, gc); gcFIXUP2(i->local_type_map, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Closure_Info)); +# endif +#endif } #define mark_closure_info_IS_ATOMIC 0 @@ -32,28 +47,43 @@ static int mark_closure_info_FIXUP(void *p, struct NewGC *gc) { static int mark_dyn_wind_cell_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Dynamic_Wind_List)); +#else + return 0; +#endif } static int mark_dyn_wind_cell_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Dynamic_Wind_List *l = (Scheme_Dynamic_Wind_List *)p; gcMARK2(l->dw, gc); gcMARK2(l->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Dynamic_Wind_List)); +# endif +#endif } static int mark_dyn_wind_cell_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Dynamic_Wind_List *l = (Scheme_Dynamic_Wind_List *)p; gcFIXUP2(l->dw, gc); gcFIXUP2(l->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Dynamic_Wind_List)); +# endif +#endif } #define mark_dyn_wind_cell_IS_ATOMIC 0 @@ -61,30 +91,45 @@ static int mark_dyn_wind_cell_FIXUP(void *p, struct NewGC *gc) { static int mark_dyn_wind_info_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Dyn_Wind)); +#else + return 0; +#endif } static int mark_dyn_wind_info_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Dyn_Wind *d = (Dyn_Wind *)p; gcMARK2(d->pre, gc); gcMARK2(d->act, gc); gcMARK2(d->post, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Dyn_Wind)); +# endif +#endif } static int mark_dyn_wind_info_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Dyn_Wind *d = (Dyn_Wind *)p; gcFIXUP2(d->pre, gc); gcFIXUP2(d->act, gc); gcFIXUP2(d->post, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Dyn_Wind)); +# endif +#endif } #define mark_dyn_wind_info_IS_ATOMIC 0 @@ -92,30 +137,45 @@ static int mark_dyn_wind_info_FIXUP(void *p, struct NewGC *gc) { static int mark_cont_mark_chain_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Mark_Chain)); +#else + return 0; +#endif } static int mark_cont_mark_chain_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Cont_Mark_Chain *c = (Scheme_Cont_Mark_Chain *)p; gcMARK2(c->key, gc); gcMARK2(c->val, gc); gcMARK2(c->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Mark_Chain)); +# endif +#endif } static int mark_cont_mark_chain_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Cont_Mark_Chain *c = (Scheme_Cont_Mark_Chain *)p; gcFIXUP2(c->key, gc); gcFIXUP2(c->val, gc); gcFIXUP2(c->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Mark_Chain)); +# endif +#endif } #define mark_cont_mark_chain_IS_ATOMIC 0 @@ -125,11 +185,15 @@ static int mark_cont_mark_chain_FIXUP(void *p, struct NewGC *gc) { #ifdef MZ_USE_JIT static int mark_lightweight_cont_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Lightweight_Continuation)); +#else + return 0; +#endif } static int mark_lightweight_cont_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Lightweight_Continuation *lw = (Scheme_Lightweight_Continuation *)p; gcMARK2(lw->saved_lwc, gc); @@ -137,11 +201,17 @@ static int mark_lightweight_cont_MARK(void *p, struct NewGC *gc) { gcMARK2(lw->runstack_slice, gc); gcMARK2(lw->cont_mark_stack_slice, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Lightweight_Continuation)); +# endif +#endif } static int mark_lightweight_cont_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Lightweight_Continuation *lw = (Scheme_Lightweight_Continuation *)p; gcFIXUP2(lw->saved_lwc, gc); @@ -149,8 +219,13 @@ static int mark_lightweight_cont_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(lw->runstack_slice, gc); gcFIXUP2(lw->cont_mark_stack_slice, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Lightweight_Continuation)); +# endif +#endif } #define mark_lightweight_cont_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_future.inc b/racket/src/racket/src/mzmark_future.inc index c09539050e..ca0ce920e0 100644 --- a/racket/src/racket/src/mzmark_future.inc +++ b/racket/src/racket/src/mzmark_future.inc @@ -3,11 +3,15 @@ #ifdef MZ_USE_FUTURES static int future_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(future_t)); +#else + return 0; +#endif } static int future_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED future_t *f = (future_t *)p; gcMARK2(f->orig_lambda, gc); gcMARK2(f->cust, gc); @@ -37,11 +41,17 @@ static int future_MARK(void *p, struct NewGC *gc) { gcMARK2(f->prev_in_fsema_queue, gc); gcMARK2(f->next_in_fsema_queue, gc); gcMARK2(f->touching, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(future_t)); +# endif +#endif } static int future_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED future_t *f = (future_t *)p; gcFIXUP2(f->orig_lambda, gc); gcFIXUP2(f->cust, gc); @@ -71,8 +81,13 @@ static int future_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(f->prev_in_fsema_queue, gc); gcFIXUP2(f->next_in_fsema_queue, gc); gcFIXUP2(f->touching, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(future_t)); +# endif +#endif } #define future_IS_ATOMIC 0 @@ -80,24 +95,39 @@ static int future_FIXUP(void *p, struct NewGC *gc) { static int fsemaphore_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(fsemaphore_t)); +#else + return 0; +#endif } static int fsemaphore_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED fsemaphore_t *s = (fsemaphore_t*)p; gcMARK2(s->queue_front, gc); gcMARK2(s->queue_end, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(fsemaphore_t)); +# endif +#endif } static int fsemaphore_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED fsemaphore_t *s = (fsemaphore_t*)p; gcFIXUP2(s->queue_front, gc); gcFIXUP2(s->queue_end, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(fsemaphore_t)); +# endif +#endif } #define fsemaphore_IS_ATOMIC 0 @@ -107,28 +137,43 @@ static int fsemaphore_FIXUP(void *p, struct NewGC *gc) { #else static int sequential_future_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(future_t)); +#else + return 0; +#endif } static int sequential_future_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED future_t *f = (future_t *)p; gcMARK2(f->orig_lambda, gc); gcMARK2(f->running_sema, gc); gcMARK2(f->retval, gc); gcMARK2(f->multiple_array, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(future_t)); +# endif +#endif } static int sequential_future_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED future_t *f = (future_t *)p; gcFIXUP2(f->orig_lambda, gc); gcFIXUP2(f->running_sema, gc); gcFIXUP2(f->retval, gc); gcFIXUP2(f->multiple_array, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(future_t)); +# endif +#endif } #define sequential_future_IS_ATOMIC 0 @@ -136,22 +181,37 @@ static int sequential_future_FIXUP(void *p, struct NewGC *gc) { static int sequential_fsemaphore_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(fsemaphore_t)); +#else + return 0; +#endif } static int sequential_fsemaphore_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED fsemaphore_t *s = (fsemaphore_t*)p; gcMARK2(s->sema, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(fsemaphore_t)); +# endif +#endif } static int sequential_fsemaphore_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED fsemaphore_t *s = (fsemaphore_t*)p; gcFIXUP2(s->sema, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(fsemaphore_t)); +# endif +#endif } #define sequential_fsemaphore_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_hash.inc b/racket/src/racket/src/mzmark_hash.inc index e28f995745..b54369148a 100644 --- a/racket/src/racket/src/mzmark_hash.inc +++ b/racket/src/racket/src/mzmark_hash.inc @@ -1,13 +1,17 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int hash_tree_val_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Hash_Tree *ht = (Scheme_Hash_Tree *)p; int popcount = hamt_popcount(ht->bitmap); - return gcBYTES_TO_WORDS(HASH_TREE_RECORD_SIZE(SCHEME_HASHTR_KIND(ht), popcount)); +#else + return 0; +#endif } static int hash_tree_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Hash_Tree *ht = (Scheme_Hash_Tree *)p; int popcount = hamt_popcount(ht->bitmap); int i; @@ -15,11 +19,17 @@ static int hash_tree_val_MARK(void *p, struct NewGC *gc) { gcMARK2(ht->els[i], gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(HASH_TREE_RECORD_SIZE(SCHEME_HASHTR_KIND(ht), popcount)); +# endif +#endif } static int hash_tree_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Hash_Tree *ht = (Scheme_Hash_Tree *)p; int popcount = hamt_popcount(ht->bitmap); int i; @@ -27,8 +37,13 @@ static int hash_tree_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(ht->els[i], gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(HASH_TREE_RECORD_SIZE(SCHEME_HASHTR_KIND(ht), popcount)); +# endif +#endif } #define hash_tree_val_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_jit.inc b/racket/src/racket/src/mzmark_jit.inc index a284f524ae..a6cbabd86d 100644 --- a/racket/src/racket/src/mzmark_jit.inc +++ b/racket/src/racket/src/mzmark_jit.inc @@ -1,6 +1,7 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int native_closure_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Native_Closure *c = (Scheme_Native_Closure *)p; int closure_size = ((Scheme_Native_Closure_Data *)GC_resolve2(c->code, gc))->closure_size; @@ -8,12 +9,15 @@ static int native_closure_SIZE(void *p, struct NewGC *gc) { closure_size = -(closure_size + 1); } - return gcBYTES_TO_WORDS((sizeof(Scheme_Native_Closure) + (closure_size - mzFLEX_DELTA) * sizeof(Scheme_Object *))); +#else + return 0; +#endif } static int native_closure_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Native_Closure *c = (Scheme_Native_Closure *)p; int closure_size = ((Scheme_Native_Closure_Data *)GC_resolve2(c->code, gc))->closure_size; @@ -37,12 +41,18 @@ static int native_closure_MARK(void *p, struct NewGC *gc) { # undef CLOSURE_DATA_TYPE } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Native_Closure) + (closure_size - mzFLEX_DELTA) * sizeof(Scheme_Object *))); +# endif +#endif } static int native_closure_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Native_Closure *c = (Scheme_Native_Closure *)p; int closure_size = ((Scheme_Native_Closure_Data *)GC_resolve2(c->code, gc))->closure_size; @@ -61,9 +71,14 @@ static int native_closure_FIXUP(void *p, struct NewGC *gc) { } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Native_Closure) + (closure_size - mzFLEX_DELTA) * sizeof(Scheme_Object *))); +# endif +#endif } #define native_closure_IS_ATOMIC 0 @@ -71,11 +86,15 @@ static int native_closure_FIXUP(void *p, struct NewGC *gc) { static int mark_jit_state_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(mz_jit_state)); +#else + return 0; +#endif } static int mark_jit_state_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED mz_jit_state *j = (mz_jit_state *)p; gcMARK2(j->mappings, gc); gcMARK2(j->self_data, gc); @@ -84,11 +103,17 @@ static int mark_jit_state_MARK(void *p, struct NewGC *gc) { gcMARK2(j->retaining_data, gc); gcMARK2(j->patch_depth, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(mz_jit_state)); +# endif +#endif } static int mark_jit_state_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED mz_jit_state *j = (mz_jit_state *)p; gcFIXUP2(j->mappings, gc); gcFIXUP2(j->self_data, gc); @@ -97,8 +122,13 @@ static int mark_jit_state_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(j->retaining_data, gc); gcFIXUP2(j->patch_depth, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(mz_jit_state)); +# endif +#endif } #define mark_jit_state_IS_ATOMIC 0 @@ -106,11 +136,15 @@ static int mark_jit_state_FIXUP(void *p, struct NewGC *gc) { static int native_unclosed_proc_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Native_Closure_Data)); +#else + return 0; +#endif } static int native_unclosed_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Native_Closure_Data *d = (Scheme_Native_Closure_Data *)p; int i; @@ -125,11 +159,17 @@ static int native_unclosed_proc_MARK(void *p, struct NewGC *gc) { } gcMARK2(d->tl_map, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Native_Closure_Data)); +# endif +#endif } static int native_unclosed_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Native_Closure_Data *d = (Scheme_Native_Closure_Data *)p; int i; @@ -144,8 +184,13 @@ static int native_unclosed_proc_FIXUP(void *p, struct NewGC *gc) { } gcFIXUP2(d->tl_map, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Native_Closure_Data)); +# endif +#endif } #define native_unclosed_proc_IS_ATOMIC 0 @@ -153,28 +198,43 @@ static int native_unclosed_proc_FIXUP(void *p, struct NewGC *gc) { static int native_unclosed_proc_plus_case_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Native_Closure_Data_Plus_Case)); +#else + return 0; +#endif } static int native_unclosed_proc_plus_case_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Native_Closure_Data_Plus_Case *d = (Scheme_Native_Closure_Data_Plus_Case *)p; native_unclosed_proc_MARK(p, gc); gcMARK2(d->case_lam, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Native_Closure_Data_Plus_Case)); +# endif +#endif } static int native_unclosed_proc_plus_case_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Native_Closure_Data_Plus_Case *d = (Scheme_Native_Closure_Data_Plus_Case *)p; native_unclosed_proc_FIXUP(p, gc); gcFIXUP2(d->case_lam, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Native_Closure_Data_Plus_Case)); +# endif +#endif } #define native_unclosed_proc_plus_case_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_letrec_check.inc b/racket/src/racket/src/mzmark_letrec_check.inc index aaa0035b59..4182a6c9ee 100644 --- a/racket/src/racket/src/mzmark_letrec_check.inc +++ b/racket/src/racket/src/mzmark_letrec_check.inc @@ -1,11 +1,15 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_letrec_check_frame_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Letrec_Check_Frame)); +#else + return 0; +#endif } static int mark_letrec_check_frame_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Letrec_Check_Frame *frame = (Letrec_Check_Frame *)p; gcMARK2(frame->def, gc); @@ -14,11 +18,17 @@ static int mark_letrec_check_frame_MARK(void *p, struct NewGC *gc) { gcMARK2(frame->head, gc); gcMARK2(frame->deferred_chain, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Letrec_Check_Frame)); +# endif +#endif } static int mark_letrec_check_frame_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Letrec_Check_Frame *frame = (Letrec_Check_Frame *)p; gcFIXUP2(frame->def, gc); @@ -27,8 +37,13 @@ static int mark_letrec_check_frame_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(frame->head, gc); gcFIXUP2(frame->deferred_chain, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Letrec_Check_Frame)); +# endif +#endif } #define mark_letrec_check_frame_IS_ATOMIC 0 @@ -36,30 +51,45 @@ static int mark_letrec_check_frame_FIXUP(void *p, struct NewGC *gc) { static int mark_scheme_deferred_expr_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Deferred_Expr)); +#else + return 0; +#endif } static int mark_scheme_deferred_expr_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Deferred_Expr *clos = (Scheme_Deferred_Expr *)p; gcMARK2(clos->expr, gc); gcMARK2(clos->frame, gc); gcMARK2(clos->chain_next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Deferred_Expr)); +# endif +#endif } static int mark_scheme_deferred_expr_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Deferred_Expr *clos = (Scheme_Deferred_Expr *)p; gcFIXUP2(clos->expr, gc); gcFIXUP2(clos->frame, gc); gcFIXUP2(clos->chain_next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Deferred_Expr)); +# endif +#endif } #define mark_scheme_deferred_expr_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_network.inc b/racket/src/racket/src/mzmark_network.inc index 389b9bfd79..493fb9fd6e 100644 --- a/racket/src/racket/src/mzmark_network.inc +++ b/racket/src/racket/src/mzmark_network.inc @@ -2,13 +2,17 @@ #ifdef USE_TCP static int mark_listener_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS listener_t *l = (listener_t *)p; - return gcBYTES_TO_WORDS(sizeof(listener_t) + ((l->count - mzFLEX_DELTA) * sizeof(tcp_t))); +#else + return 0; +#endif } static int mark_listener_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED listener_t *l = (listener_t *)p; @@ -17,11 +21,17 @@ static int mark_listener_MARK(void *p, struct NewGC *gc) { gcMARK2(l->pfd, gc); # endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(listener_t) + ((l->count - mzFLEX_DELTA) * sizeof(tcp_t))); +# endif +#endif } static int mark_listener_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED listener_t *l = (listener_t *)p; @@ -30,8 +40,13 @@ static int mark_listener_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(l->pfd, gc); # endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(listener_t) + ((l->count - mzFLEX_DELTA) * sizeof(tcp_t))); +# endif +#endif } #define mark_listener_IS_ATOMIC 0 @@ -39,28 +54,43 @@ static int mark_listener_FIXUP(void *p, struct NewGC *gc) { static int mark_tcp_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Tcp)); +#else + return 0; +#endif } static int mark_tcp_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Tcp *tcp = (Scheme_Tcp *)p; gcMARK2(tcp->b.buffer, gc); gcMARK2(tcp->b.out_buffer, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Tcp)); +# endif +#endif } static int mark_tcp_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Tcp *tcp = (Scheme_Tcp *)p; gcFIXUP2(tcp->b.buffer, gc); gcFIXUP2(tcp->b.out_buffer, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Tcp)); +# endif +#endif } #define mark_tcp_IS_ATOMIC 0 @@ -69,28 +99,43 @@ static int mark_tcp_FIXUP(void *p, struct NewGC *gc) { # ifdef UDP_IS_SUPPORTED static int mark_udp_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_UDP)); +#else + return 0; +#endif } static int mark_udp_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_UDP *udp = (Scheme_UDP *)p; gcMARK2(udp->previous_from_addr, gc); gcMARK2(udp->mref, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_UDP)); +# endif +#endif } static int mark_udp_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_UDP *udp = (Scheme_UDP *)p; gcFIXUP2(udp->previous_from_addr, gc); gcFIXUP2(udp->mref, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_UDP)); +# endif +#endif } #define mark_udp_IS_ATOMIC 0 @@ -98,11 +143,15 @@ static int mark_udp_FIXUP(void *p, struct NewGC *gc) { static int mark_udp_evt_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_UDP_Evt)); +#else + return 0; +#endif } static int mark_udp_evt_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_UDP_Evt *uw = (Scheme_UDP_Evt *)p; gcMARK2(uw->udp, gc); @@ -110,11 +159,17 @@ static int mark_udp_evt_MARK(void *p, struct NewGC *gc) { gcMARK2(uw->dest_addrs, gc); gcMARK2(uw->dest_addr_lens, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_UDP_Evt)); +# endif +#endif } static int mark_udp_evt_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_UDP_Evt *uw = (Scheme_UDP_Evt *)p; gcFIXUP2(uw->udp, gc); @@ -122,8 +177,13 @@ static int mark_udp_evt_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(uw->dest_addrs, gc); gcFIXUP2(uw->dest_addr_lens, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_UDP_Evt)); +# endif +#endif } #define mark_udp_evt_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_optimize.inc b/racket/src/racket/src/mzmark_optimize.inc index 20ecbdfd53..81e923f94b 100644 --- a/racket/src/racket/src/mzmark_optimize.inc +++ b/racket/src/racket/src/mzmark_optimize.inc @@ -1,11 +1,15 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_optimize_info_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Optimize_Info)); +#else + return 0; +#endif } static int mark_optimize_info_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Optimize_Info *i = (Optimize_Info *)p; gcMARK2(i->stat_dists, gc); @@ -21,11 +25,17 @@ static int mark_optimize_info_MARK(void *p, struct NewGC *gc) { gcMARK2(i->logger, gc); gcMARK2(i->types, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Optimize_Info)); +# endif +#endif } static int mark_optimize_info_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Optimize_Info *i = (Optimize_Info *)p; gcFIXUP2(i->stat_dists, gc); @@ -41,8 +51,13 @@ static int mark_optimize_info_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(i->logger, gc); gcFIXUP2(i->types, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Optimize_Info)); +# endif +#endif } #define mark_optimize_info_IS_ATOMIC 0 @@ -50,26 +65,41 @@ static int mark_optimize_info_FIXUP(void *p, struct NewGC *gc) { static int mark_once_used_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Once_Used)); +#else + return 0; +#endif } static int mark_once_used_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Once_Used *o = (Scheme_Once_Used *)p; gcMARK2(o->expr, gc); gcMARK2(o->info, gc); gcMARK2(o->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Once_Used)); +# endif +#endif } static int mark_once_used_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Once_Used *o = (Scheme_Once_Used *)p; gcFIXUP2(o->expr, gc); gcFIXUP2(o->info, gc); gcFIXUP2(o->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Once_Used)); +# endif +#endif } #define mark_once_used_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_place.inc b/racket/src/racket/src/mzmark_place.inc index e76c463670..4be6e2a27e 100644 --- a/racket/src/racket/src/mzmark_place.inc +++ b/racket/src/racket/src/mzmark_place.inc @@ -1,24 +1,39 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int place_bi_channel_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Place_Bi_Channel)); +#else + return 0; +#endif } static int place_bi_channel_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Place_Bi_Channel *pbc = (Scheme_Place_Bi_Channel *)p; gcMARK2(pbc->link, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place_Bi_Channel)); +# endif +#endif } static int place_bi_channel_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Place_Bi_Channel *pbc = (Scheme_Place_Bi_Channel *)p; gcFIXUP2(pbc->link, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place_Bi_Channel)); +# endif +#endif } #define place_bi_channel_val_IS_ATOMIC 0 @@ -26,18 +41,33 @@ static int place_bi_channel_val_FIXUP(void *p, struct NewGC *gc) { static int place_object_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Place_Object)); +#else + return 0; +#endif } static int place_object_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place_Object)); +# endif +#endif } static int place_object_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place_Object)); +# endif +#endif } #define place_object_val_IS_ATOMIC 1 @@ -45,11 +75,15 @@ static int place_object_val_FIXUP(void *p, struct NewGC *gc) { static int place_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Place)); +#else + return 0; +#endif } static int place_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Place *pr = (Scheme_Place *)p; gcMARK2(pr->channel, gc); gcMARK2(pr->mref, gc); @@ -58,11 +92,17 @@ static int place_val_MARK(void *p, struct NewGC *gc) { gcMARK2(pr->prev, gc); gcMARK2(pr->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place)); +# endif +#endif } static int place_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Place *pr = (Scheme_Place *)p; gcFIXUP2(pr->channel, gc); gcFIXUP2(pr->mref, gc); @@ -71,8 +111,13 @@ static int place_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(pr->prev, gc); gcFIXUP2(pr->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place)); +# endif +#endif } #define place_val_IS_ATOMIC 0 @@ -80,11 +125,15 @@ static int place_val_FIXUP(void *p, struct NewGC *gc) { static int place_async_channel_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Place_Async_Channel)); +#else + return 0; +#endif } static int place_async_channel_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Place_Async_Channel *pac = (Scheme_Place_Async_Channel *)p; Scheme_Object *pr; int i, j, sz; @@ -106,11 +155,17 @@ static int place_async_channel_val_MARK(void *p, struct NewGC *gc) { j = ((j + 1) % sz); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place_Async_Channel)); +# endif +#endif } static int place_async_channel_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Place_Async_Channel *pac = (Scheme_Place_Async_Channel *)p; Scheme_Object *pr; int i, j, sz; @@ -132,8 +187,13 @@ static int place_async_channel_val_FIXUP(void *p, struct NewGC *gc) { j = ((j + 1) % sz); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Place_Async_Channel)); +# endif +#endif } #define place_async_channel_val_IS_ATOMIC 0 @@ -141,24 +201,39 @@ static int place_async_channel_val_FIXUP(void *p, struct NewGC *gc) { static int serialized_file_fd_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Serialized_File_FD)); +#else + return 0; +#endif } static int serialized_file_fd_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Serialized_File_FD *ffd = (Scheme_Serialized_File_FD *) p; gcMARK2(ffd->name, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Serialized_File_FD)); +# endif +#endif } static int serialized_file_fd_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Serialized_File_FD *ffd = (Scheme_Serialized_File_FD *) p; gcFIXUP2(ffd->name, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Serialized_File_FD)); +# endif +#endif } #define serialized_file_fd_val_IS_ATOMIC 0 @@ -166,24 +241,39 @@ static int serialized_file_fd_val_FIXUP(void *p, struct NewGC *gc) { static int serialized_socket_fd_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Serialized_Socket_FD)); +#else + return 0; +#endif } static int serialized_socket_fd_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Serialized_Socket_FD *sfd = (Scheme_Serialized_Socket_FD *) p; gcMARK2(sfd->name, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Serialized_Socket_FD)); +# endif +#endif } static int serialized_socket_fd_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Serialized_Socket_FD *sfd = (Scheme_Serialized_Socket_FD *) p; gcFIXUP2(sfd->name, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Serialized_Socket_FD)); +# endif +#endif } #define serialized_socket_fd_val_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_port.inc b/racket/src/racket/src/mzmark_port.inc index 207b0c4f7f..845feea427 100644 --- a/racket/src/racket/src/mzmark_port.inc +++ b/racket/src/racket/src/mzmark_port.inc @@ -1,26 +1,41 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_input_file_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Input_File)); +#else + return 0; +#endif } static int mark_input_file_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Input_File *i = (Scheme_Input_File *)p; gcMARK2(i->f, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Input_File)); +# endif +#endif } static int mark_input_file_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Input_File *i = (Scheme_Input_File *)p; gcFIXUP2(i->f, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Input_File)); +# endif +#endif } #define mark_input_file_IS_ATOMIC 0 @@ -28,26 +43,41 @@ static int mark_input_file_FIXUP(void *p, struct NewGC *gc) { static int mark_output_file_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Output_File)); +#else + return 0; +#endif } static int mark_output_file_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Output_File *o = (Scheme_Output_File *)p; gcMARK2(o->f, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Output_File)); +# endif +#endif } static int mark_output_file_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Output_File *o = (Scheme_Output_File *)p; gcFIXUP2(o->f, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Output_File)); +# endif +#endif } #define mark_output_file_IS_ATOMIC 0 @@ -56,30 +86,45 @@ static int mark_output_file_FIXUP(void *p, struct NewGC *gc) { #ifdef MZ_FDS static int mark_input_fd_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_FD)); +#else + return 0; +#endif } static int mark_input_fd_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_FD *fd = (Scheme_FD *)p; gcMARK2(fd->buffer, gc); gcMARK2(fd->refcount, gc); gcMARK2(fd->flush_handle, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_FD)); +# endif +#endif } static int mark_input_fd_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_FD *fd = (Scheme_FD *)p; gcFIXUP2(fd->buffer, gc); gcFIXUP2(fd->refcount, gc); gcFIXUP2(fd->flush_handle, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_FD)); +# endif +#endif } #define mark_input_fd_IS_ATOMIC 0 @@ -89,26 +134,41 @@ static int mark_input_fd_FIXUP(void *p, struct NewGC *gc) { #if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) static int mark_system_child_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(System_Child)); +#else + return 0; +#endif } static int mark_system_child_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED System_Child *sc = (System_Child *)p; gcMARK2(sc->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(System_Child)); +# endif +#endif } static int mark_system_child_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED System_Child *sc = (System_Child *)p; gcFIXUP2(sc->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(System_Child)); +# endif +#endif } #define mark_system_child_IS_ATOMIC 0 @@ -118,28 +178,43 @@ static int mark_system_child_FIXUP(void *p, struct NewGC *gc) { #ifdef USE_OSKIT_CONSOLE static int mark_oskit_console_input_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(osk_console_input)); +#else + return 0; +#endif } static int mark_oskit_console_input_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED osk_console_input *c = (osk_console_input *)p; gcMARK2(c->buffer, gc); gcMARK2(c->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(osk_console_input)); +# endif +#endif } static int mark_oskit_console_input_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED osk_console_input *c = (osk_console_input *)p; gcFIXUP2(c->buffer, gc); gcFIXUP2(c->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(osk_console_input)); +# endif +#endif } #define mark_oskit_console_input_IS_ATOMIC 0 @@ -148,28 +223,43 @@ static int mark_oskit_console_input_FIXUP(void *p, struct NewGC *gc) { #endif static int mark_subprocess_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Subprocess)); +#else + return 0; +#endif } static int mark_subprocess_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED #ifndef WINDOWS_PROCESSES Scheme_Subprocess *sp = (Scheme_Subprocess *)p; gcMARK2(sp->handle, gc); gcMARK2(sp->mref, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Subprocess)); +# endif +#endif } static int mark_subprocess_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED #ifndef WINDOWS_PROCESSES Scheme_Subprocess *sp = (Scheme_Subprocess *)p; gcFIXUP2(sp->handle, gc); gcFIXUP2(sp->mref, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Subprocess)); +# endif +#endif } #define mark_subprocess_IS_ATOMIC 0 @@ -177,26 +267,41 @@ static int mark_subprocess_FIXUP(void *p, struct NewGC *gc) { static int mark_read_write_evt_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Read_Write_Evt)); +#else + return 0; +#endif } static int mark_read_write_evt_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Read_Write_Evt *rww = (Scheme_Read_Write_Evt *)p; gcMARK2(rww->port, gc); gcMARK2(rww->v, gc); gcMARK2(rww->str, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Read_Write_Evt)); +# endif +#endif } static int mark_read_write_evt_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Read_Write_Evt *rww = (Scheme_Read_Write_Evt *)p; gcFIXUP2(rww->port, gc); gcFIXUP2(rww->v, gc); gcFIXUP2(rww->str, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Read_Write_Evt)); +# endif +#endif } #define mark_read_write_evt_IS_ATOMIC 0 @@ -204,24 +309,39 @@ static int mark_read_write_evt_FIXUP(void *p, struct NewGC *gc) { static int mark_filesystem_change_evt_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Filesystem_Change_Evt)); +#else + return 0; +#endif } static int mark_filesystem_change_evt_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Filesystem_Change_Evt *fc = (Scheme_Filesystem_Change_Evt *)p; gcMARK2(fc->sema, gc); gcMARK2(fc->mref, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Filesystem_Change_Evt)); +# endif +#endif } static int mark_filesystem_change_evt_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Filesystem_Change_Evt *fc = (Scheme_Filesystem_Change_Evt *)p; gcFIXUP2(fc->sema, gc); gcFIXUP2(fc->mref, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Filesystem_Change_Evt)); +# endif +#endif } #define mark_filesystem_change_evt_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_portfun.inc b/racket/src/racket/src/mzmark_portfun.inc index a6b415ea86..df14dafc34 100644 --- a/racket/src/racket/src/mzmark_portfun.inc +++ b/racket/src/racket/src/mzmark_portfun.inc @@ -1,11 +1,15 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_load_handler_data_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(LoadHandlerData)); +#else + return 0; +#endif } static int mark_load_handler_data_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED LoadHandlerData *d = (LoadHandlerData *)p; gcMARK2(d->config, gc); @@ -14,11 +18,17 @@ static int mark_load_handler_data_MARK(void *p, struct NewGC *gc) { gcMARK2(d->stxsrc, gc); gcMARK2(d->expected_module, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(LoadHandlerData)); +# endif +#endif } static int mark_load_handler_data_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED LoadHandlerData *d = (LoadHandlerData *)p; gcFIXUP2(d->config, gc); @@ -27,8 +37,13 @@ static int mark_load_handler_data_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(d->stxsrc, gc); gcFIXUP2(d->expected_module, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(LoadHandlerData)); +# endif +#endif } #define mark_load_handler_data_IS_ATOMIC 0 @@ -36,26 +51,41 @@ static int mark_load_handler_data_FIXUP(void *p, struct NewGC *gc) { static int mark_indexed_string_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Indexed_String)); +#else + return 0; +#endif } static int mark_indexed_string_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Indexed_String *is = (Scheme_Indexed_String *)p; gcMARK2(is->string, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Indexed_String)); +# endif +#endif } static int mark_indexed_string_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Indexed_String *is = (Scheme_Indexed_String *)p; gcFIXUP2(is->string, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Indexed_String)); +# endif +#endif } #define mark_indexed_string_IS_ATOMIC 0 @@ -63,11 +93,15 @@ static int mark_indexed_string_FIXUP(void *p, struct NewGC *gc) { static int mark_user_input_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(User_Input_Port)); +#else + return 0; +#endif } static int mark_user_input_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED User_Input_Port *uip = (User_Input_Port *)p; gcMARK2(uip->read_proc, gc); @@ -81,11 +115,17 @@ static int mark_user_input_MARK(void *p, struct NewGC *gc) { gcMARK2(uip->reuse_str, gc); gcMARK2(uip->peeked, gc); gcMARK2(uip->prefix_pipe, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(User_Input_Port)); +# endif +#endif } static int mark_user_input_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED User_Input_Port *uip = (User_Input_Port *)p; gcFIXUP2(uip->read_proc, gc); @@ -99,8 +139,13 @@ static int mark_user_input_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(uip->reuse_str, gc); gcFIXUP2(uip->peeked, gc); gcFIXUP2(uip->prefix_pipe, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(User_Input_Port)); +# endif +#endif } #define mark_user_input_IS_ATOMIC 0 @@ -108,11 +153,15 @@ static int mark_user_input_FIXUP(void *p, struct NewGC *gc) { static int mark_user_output_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(User_Output_Port)); +#else + return 0; +#endif } static int mark_user_output_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED User_Output_Port *uop = (User_Output_Port *)p; gcMARK2(uop->evt, gc); @@ -125,11 +174,17 @@ static int mark_user_output_MARK(void *p, struct NewGC *gc) { gcMARK2(uop->buffer_mode_proc, gc); gcMARK2(uop->close_proc, gc); gcMARK2(uop->buffer_pipe, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(User_Output_Port)); +# endif +#endif } static int mark_user_output_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED User_Output_Port *uop = (User_Output_Port *)p; gcFIXUP2(uop->evt, gc); @@ -142,8 +197,13 @@ static int mark_user_output_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(uop->buffer_mode_proc, gc); gcFIXUP2(uop->close_proc, gc); gcFIXUP2(uop->buffer_pipe, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(User_Output_Port)); +# endif +#endif } #define mark_user_output_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_print.inc b/racket/src/racket/src/mzmark_print.inc index 027545ae6b..f96d4d27bd 100644 --- a/racket/src/racket/src/mzmark_print.inc +++ b/racket/src/racket/src/mzmark_print.inc @@ -1,30 +1,45 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_print_params_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(PrintParams)); +#else + return 0; +#endif } static int mark_print_params_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED PrintParams *pp = (PrintParams *)p; gcMARK2(pp->inspector, gc); gcMARK2(pp->print_port, gc); gcMARK2(pp->print_buffer, gc); gcMARK2(pp->depth_delta, gc); gcMARK2(pp->uq_ht, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(PrintParams)); +# endif +#endif } static int mark_print_params_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED PrintParams *pp = (PrintParams *)p; gcFIXUP2(pp->inspector, gc); gcFIXUP2(pp->print_port, gc); gcFIXUP2(pp->print_buffer, gc); gcFIXUP2(pp->depth_delta, gc); gcFIXUP2(pp->uq_ht, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(PrintParams)); +# endif +#endif } #define mark_print_params_IS_ATOMIC 0 @@ -32,11 +47,15 @@ static int mark_print_params_FIXUP(void *p, struct NewGC *gc) { static int mark_marshal_tables_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Marshal_Tables)); +#else + return 0; +#endif } static int mark_marshal_tables_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Marshal_Tables *mt = (Scheme_Marshal_Tables *)p; gcMARK2(mt->symtab, gc); gcMARK2(mt->st_refs, gc); @@ -55,11 +74,17 @@ static int mark_marshal_tables_MARK(void *p, struct NewGC *gc) { gcMARK2(mt->shared_offsets, gc); gcMARK2(mt->path_cache, gc); gcMARK2(mt->sorted_keys, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Marshal_Tables)); +# endif +#endif } static int mark_marshal_tables_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Marshal_Tables *mt = (Scheme_Marshal_Tables *)p; gcFIXUP2(mt->symtab, gc); gcFIXUP2(mt->st_refs, gc); @@ -78,8 +103,13 @@ static int mark_marshal_tables_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(mt->shared_offsets, gc); gcFIXUP2(mt->path_cache, gc); gcFIXUP2(mt->sorted_keys, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Marshal_Tables)); +# endif +#endif } #define mark_marshal_tables_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_read.inc b/racket/src/racket/src/mzmark_read.inc index 174103aba0..64cdf82a79 100644 --- a/racket/src/racket/src/mzmark_read.inc +++ b/racket/src/racket/src/mzmark_read.inc @@ -1,18 +1,33 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_indent_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Indent)); +#else + return 0; +#endif } static int mark_indent_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Indent)); +# endif +#endif } static int mark_indent_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Indent)); +# endif +#endif } #define mark_indent_IS_ATOMIC 1 @@ -20,11 +35,15 @@ static int mark_indent_FIXUP(void *p, struct NewGC *gc) { static int mark_cport_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(CPort)); +#else + return 0; +#endif } static int mark_cport_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED CPort *cp = (CPort *)p; gcMARK2(cp->start, gc); gcMARK2(cp->orig_port, gc); @@ -37,11 +56,17 @@ static int mark_cport_MARK(void *p, struct NewGC *gc) { gcMARK2(cp->shared_offsets, gc); gcMARK2(cp->delay_info, gc); gcMARK2(cp->symtab_refs, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(CPort)); +# endif +#endif } static int mark_cport_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED CPort *cp = (CPort *)p; gcFIXUP2(cp->start, gc); gcFIXUP2(cp->orig_port, gc); @@ -54,8 +79,13 @@ static int mark_cport_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(cp->shared_offsets, gc); gcFIXUP2(cp->delay_info, gc); gcFIXUP2(cp->symtab_refs, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(CPort)); +# endif +#endif } #define mark_cport_IS_ATOMIC 0 @@ -63,28 +93,43 @@ static int mark_cport_FIXUP(void *p, struct NewGC *gc) { static int mark_readtable_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Readtable)); +#else + return 0; +#endif } static int mark_readtable_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Readtable *t = (Readtable *)p; gcMARK2(t->mapping, gc); gcMARK2(t->fast_mapping, gc); gcMARK2(t->symbol_parser, gc); gcMARK2(t->names, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Readtable)); +# endif +#endif } static int mark_readtable_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Readtable *t = (Readtable *)p; gcFIXUP2(t->mapping, gc); gcFIXUP2(t->fast_mapping, gc); gcFIXUP2(t->symbol_parser, gc); gcFIXUP2(t->names, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Readtable)); +# endif +#endif } #define mark_readtable_IS_ATOMIC 0 @@ -92,30 +137,45 @@ static int mark_readtable_FIXUP(void *p, struct NewGC *gc) { static int mark_read_params_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(ReadParams)); +#else + return 0; +#endif } static int mark_read_params_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED ReadParams *rp = (ReadParams *)p; gcMARK2(rp->table, gc); gcMARK2(rp->magic_sym, gc); gcMARK2(rp->magic_val, gc); gcMARK2(rp->delay_load_info, gc); gcMARK2(rp->read_relative_path, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(ReadParams)); +# endif +#endif } static int mark_read_params_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED ReadParams *rp = (ReadParams *)p; gcFIXUP2(rp->table, gc); gcFIXUP2(rp->magic_sym, gc); gcFIXUP2(rp->magic_val, gc); gcFIXUP2(rp->delay_load_info, gc); gcFIXUP2(rp->read_relative_path, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(ReadParams)); +# endif +#endif } #define mark_read_params_IS_ATOMIC 0 @@ -123,11 +183,15 @@ static int mark_read_params_FIXUP(void *p, struct NewGC *gc) { static int mark_delay_load_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Load_Delay)); +#else + return 0; +#endif } static int mark_delay_load_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Load_Delay *ld = (Scheme_Load_Delay *)p; gcMARK2(ld->path, gc); gcMARK2(ld->symtab, gc); @@ -137,11 +201,17 @@ static int mark_delay_load_MARK(void *p, struct NewGC *gc) { gcMARK2(ld->current_rp, gc); gcMARK2(ld->cached, gc); gcMARK2(ld->cached_port, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Load_Delay)); +# endif +#endif } static int mark_delay_load_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Load_Delay *ld = (Scheme_Load_Delay *)p; gcFIXUP2(ld->path, gc); gcFIXUP2(ld->symtab, gc); @@ -151,8 +221,13 @@ static int mark_delay_load_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(ld->current_rp, gc); gcFIXUP2(ld->cached, gc); gcFIXUP2(ld->cached_port, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Load_Delay)); +# endif +#endif } #define mark_delay_load_IS_ATOMIC 0 @@ -160,28 +235,43 @@ static int mark_delay_load_FIXUP(void *p, struct NewGC *gc) { static int mark_unmarshal_tables_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Unmarshal_Tables)); +#else + return 0; +#endif } static int mark_unmarshal_tables_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcMARK2(ut->rns, gc); gcMARK2(ut->multi_scope_pairs, gc); gcMARK2(ut->rp, gc); gcMARK2(ut->decoded, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Unmarshal_Tables)); +# endif +#endif } static int mark_unmarshal_tables_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcFIXUP2(ut->rns, gc); gcFIXUP2(ut->multi_scope_pairs, gc); gcFIXUP2(ut->rp, gc); gcFIXUP2(ut->decoded, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Unmarshal_Tables)); +# endif +#endif } #define mark_unmarshal_tables_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_regexp.inc b/racket/src/racket/src/mzmark_regexp.inc index c718864ee6..52215cc9f2 100644 --- a/racket/src/racket/src/mzmark_regexp.inc +++ b/racket/src/racket/src/mzmark_regexp.inc @@ -1,25 +1,40 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_regexp_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS regexp *r = (regexp *)p; - return gcBYTES_TO_WORDS((sizeof(regexp) + r->regsize)); +#else + return 0; +#endif } static int mark_regexp_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED regexp *r = (regexp *)p; gcMARK2(r->source, gc); gcMARK2(r->regstart, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(regexp) + r->regsize)); +# endif +#endif } static int mark_regexp_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED regexp *r = (regexp *)p; gcFIXUP2(r->source, gc); gcFIXUP2(r->regstart, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(regexp) + r->regsize)); +# endif +#endif } #define mark_regexp_IS_ATOMIC 0 @@ -27,11 +42,15 @@ static int mark_regexp_FIXUP(void *p, struct NewGC *gc) { static int mark_regwork_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Regwork)); +#else + return 0; +#endif } static int mark_regwork_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Regwork *r = (Regwork *)p; gcMARK2(r->str, gc); gcMARK2(r->instr, gc); @@ -45,11 +64,17 @@ static int mark_regwork_MARK(void *p, struct NewGC *gc) { gcMARK2(r->prefix, gc); gcMARK2(r->lazy_string, gc); gcMARK2(r->rewind_stack, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Regwork)); +# endif +#endif } static int mark_regwork_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Regwork *r = (Regwork *)p; gcFIXUP2(r->str, gc); gcFIXUP2(r->instr, gc); @@ -63,8 +88,13 @@ static int mark_regwork_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(r->prefix, gc); gcFIXUP2(r->lazy_string, gc); gcFIXUP2(r->rewind_stack, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Regwork)); +# endif +#endif } #define mark_regwork_IS_ATOMIC 0 @@ -72,24 +102,39 @@ static int mark_regwork_FIXUP(void *p, struct NewGC *gc) { static int mark_lazy_string_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(rx_lazy_str_t)); +#else + return 0; +#endif } static int mark_lazy_string_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED rx_lazy_str_t *ls = (rx_lazy_str_t *)p; gcMARK2(ls->s, gc); gcMARK2(ls->chars, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(rx_lazy_str_t)); +# endif +#endif } static int mark_lazy_string_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED rx_lazy_str_t *ls = (rx_lazy_str_t *)p; gcFIXUP2(ls->s, gc); gcFIXUP2(ls->chars, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(rx_lazy_str_t)); +# endif +#endif } #define mark_lazy_string_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_resolve.inc b/racket/src/racket/src/mzmark_resolve.inc index d9c7b662bd..0b99119966 100644 --- a/racket/src/racket/src/mzmark_resolve.inc +++ b/racket/src/racket/src/mzmark_resolve.inc @@ -1,11 +1,15 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_resolve_info_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Resolve_Info)); +#else + return 0; +#endif } static int mark_resolve_info_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Resolve_Info *i = (Resolve_Info *)p; gcMARK2(i->prefix, gc); @@ -19,11 +23,17 @@ static int mark_resolve_info_MARK(void *p, struct NewGC *gc) { gcMARK2(i->lifted, gc); gcMARK2(i->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Resolve_Info)); +# endif +#endif } static int mark_resolve_info_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Resolve_Info *i = (Resolve_Info *)p; gcFIXUP2(i->prefix, gc); @@ -37,8 +47,13 @@ static int mark_resolve_info_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(i->lifted, gc); gcFIXUP2(i->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Resolve_Info)); +# endif +#endif } #define mark_resolve_info_IS_ATOMIC 0 @@ -46,11 +61,15 @@ static int mark_resolve_info_FIXUP(void *p, struct NewGC *gc) { static int mark_unresolve_info_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); +#else + return 0; +#endif } static int mark_unresolve_info_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Unresolve_Info *i = (Unresolve_Info *)p; gcMARK2(i->flags, gc); @@ -65,11 +84,17 @@ static int mark_unresolve_info_MARK(void *p, struct NewGC *gc) { gcMARK2(i->ref_args, gc); gcMARK2(i->ref_lifts, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); +# endif +#endif } static int mark_unresolve_info_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Unresolve_Info *i = (Unresolve_Info *)p; gcFIXUP2(i->flags, gc); @@ -84,8 +109,13 @@ static int mark_unresolve_info_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(i->ref_args, gc); gcFIXUP2(i->ref_lifts, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Unresolve_Info)); +# endif +#endif } #define mark_unresolve_info_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_salloc.inc b/racket/src/racket/src/mzmark_salloc.inc index b3d309e026..2491c1ecb7 100644 --- a/racket/src/racket/src/mzmark_salloc.inc +++ b/racket/src/racket/src/mzmark_salloc.inc @@ -1,30 +1,45 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_finalization_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Finalization)); +#else + return 0; +#endif } static int mark_finalization_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Finalization *f = (Finalization *)p; gcMARK2(f->data, gc); gcMARK2(f->next, gc); gcMARK2(f->prev, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Finalization)); +# endif +#endif } static int mark_finalization_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Finalization *f = (Finalization *)p; gcFIXUP2(f->data, gc); gcFIXUP2(f->next, gc); gcFIXUP2(f->prev, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Finalization)); +# endif +#endif } #define mark_finalization_IS_ATOMIC 0 @@ -32,11 +47,15 @@ static int mark_finalization_FIXUP(void *p, struct NewGC *gc) { static int mark_finalizations_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Finalizations)); +#else + return 0; +#endif } static int mark_finalizations_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Finalizations *f = (Finalizations *)p; gcMARK2(f->scheme_first, gc); @@ -45,11 +64,17 @@ static int mark_finalizations_MARK(void *p, struct NewGC *gc) { gcMARK2(f->prim_last, gc); gcMARK2(f->ext_data, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Finalizations)); +# endif +#endif } static int mark_finalizations_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Finalizations *f = (Finalizations *)p; gcFIXUP2(f->scheme_first, gc); @@ -58,8 +83,13 @@ static int mark_finalizations_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(f->prim_last, gc); gcFIXUP2(f->ext_data, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Finalizations)); +# endif +#endif } #define mark_finalizations_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_sema.inc b/racket/src/racket/src/mzmark_sema.inc index b06bd137a4..8316e203df 100644 --- a/racket/src/racket/src/mzmark_sema.inc +++ b/racket/src/racket/src/mzmark_sema.inc @@ -1,11 +1,15 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_channel_syncer_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Channel_Syncer)); +#else + return 0; +#endif } static int mark_channel_syncer_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Channel_Syncer *w = (Scheme_Channel_Syncer *)p; gcMARK2(w->p, gc); @@ -14,11 +18,17 @@ static int mark_channel_syncer_MARK(void *p, struct NewGC *gc) { gcMARK2(w->syncing, gc); gcMARK2(w->obj, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Channel_Syncer)); +# endif +#endif } static int mark_channel_syncer_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Channel_Syncer *w = (Scheme_Channel_Syncer *)p; gcFIXUP2(w->p, gc); @@ -27,8 +37,13 @@ static int mark_channel_syncer_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(w->syncing, gc); gcFIXUP2(w->obj, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Channel_Syncer)); +# endif +#endif } #define mark_channel_syncer_IS_ATOMIC 0 @@ -36,18 +51,33 @@ static int mark_channel_syncer_FIXUP(void *p, struct NewGC *gc) { static int mark_alarm_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Alarm)); +#else + return 0; +#endif } static int mark_alarm_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Alarm)); +# endif +#endif } static int mark_alarm_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Alarm)); +# endif +#endif } #define mark_alarm_IS_ATOMIC 1 diff --git a/racket/src/racket/src/mzmark_sfs.inc b/racket/src/racket/src/mzmark_sfs.inc index 5db7e64664..dc67823805 100644 --- a/racket/src/racket/src/mzmark_sfs.inc +++ b/racket/src/racket/src/mzmark_sfs.inc @@ -1,30 +1,45 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_sfs_info_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(SFS_Info)); +#else + return 0; +#endif } static int mark_sfs_info_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED SFS_Info *i = (SFS_Info *)p; gcMARK2(i->max_used, gc); gcMARK2(i->max_calls, gc); gcMARK2(i->saved, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(SFS_Info)); +# endif +#endif } static int mark_sfs_info_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED SFS_Info *i = (SFS_Info *)p; gcFIXUP2(i->max_used, gc); gcFIXUP2(i->max_calls, gc); gcFIXUP2(i->saved, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(SFS_Info)); +# endif +#endif } #define mark_sfs_info_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_string.inc b/racket/src/racket/src/mzmark_string.inc index 74b8c4d23e..a4191f0d41 100644 --- a/racket/src/racket/src/mzmark_string.inc +++ b/racket/src/racket/src/mzmark_string.inc @@ -1,22 +1,37 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_string_convert_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Converter)); +#else + return 0; +#endif } static int mark_string_convert_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Converter *c = (Scheme_Converter *)p; gcMARK2(c->mref, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Converter)); +# endif +#endif } static int mark_string_convert_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Converter *c = (Scheme_Converter *)p; gcFIXUP2(c->mref, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Converter)); +# endif +#endif } #define mark_string_convert_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_struct.inc b/racket/src/racket/src/mzmark_struct.inc index a50e74d1c6..87bb81ee64 100644 --- a/racket/src/racket/src/mzmark_struct.inc +++ b/racket/src/racket/src/mzmark_struct.inc @@ -2,15 +2,19 @@ #ifdef MZ_USE_PLACES static int mark_serialized_struct_val_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Serialized_Structure *s = (Scheme_Serialized_Structure *)p; int num_slots = s->num_slots; - return gcBYTES_TO_WORDS((sizeof(Scheme_Serialized_Structure) + ((num_slots - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +#else + return 0; +#endif } static int mark_serialized_struct_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Serialized_Structure *s = (Scheme_Serialized_Structure *)p; int num_slots = s->num_slots; @@ -21,12 +25,18 @@ static int mark_serialized_struct_val_MARK(void *p, struct NewGC *gc) { for(i = num_slots; i--; ) gcMARK2(s->slots[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Serialized_Structure) + ((num_slots - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } static int mark_serialized_struct_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Serialized_Structure *s = (Scheme_Serialized_Structure *)p; int num_slots = s->num_slots; @@ -37,9 +47,14 @@ static int mark_serialized_struct_val_FIXUP(void *p, struct NewGC *gc) { for(i = num_slots; i--; ) gcFIXUP2(s->slots[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Serialized_Structure) + ((num_slots - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } #define mark_serialized_struct_val_IS_ATOMIC 0 @@ -48,15 +63,19 @@ static int mark_serialized_struct_val_FIXUP(void *p, struct NewGC *gc) { #endif static int mark_struct_val_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Structure *s = (Scheme_Structure *)p; int num_slots = ((Scheme_Struct_Type *)GC_resolve2(s->stype, gc))->num_slots; - return gcBYTES_TO_WORDS((sizeof(Scheme_Structure) + ((num_slots - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +#else + return 0; +#endif } static int mark_struct_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Structure *s = (Scheme_Structure *)p; int num_slots = ((Scheme_Struct_Type *)GC_resolve2(s->stype, gc))->num_slots; @@ -67,12 +86,18 @@ static int mark_struct_val_MARK(void *p, struct NewGC *gc) { for(i = num_slots; i--; ) gcMARK2(s->slots[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Structure) + ((num_slots - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } static int mark_struct_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Structure *s = (Scheme_Structure *)p; int num_slots = ((Scheme_Struct_Type *)GC_resolve2(s->stype, gc))->num_slots; @@ -83,9 +108,14 @@ static int mark_struct_val_FIXUP(void *p, struct NewGC *gc) { for(i = num_slots; i--; ) gcFIXUP2(s->slots[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Structure) + ((num_slots - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } #define mark_struct_val_IS_ATOMIC 0 @@ -93,15 +123,19 @@ static int mark_struct_val_FIXUP(void *p, struct NewGC *gc) { static int mark_struct_type_val_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Struct_Type *t = (Scheme_Struct_Type *)p; - return gcBYTES_TO_WORDS((sizeof(Scheme_Struct_Type) + ((t->name_pos + 1 - mzFLEX_DELTA) * sizeof(Scheme_Struct_Type *)))); +#else + return 0; +#endif } static int mark_struct_type_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Struct_Type *t = (Scheme_Struct_Type *)p; int i; @@ -119,13 +153,19 @@ static int mark_struct_type_val_MARK(void *p, struct NewGC *gc) { gcMARK2(t->guard, gc); gcMARK2(t->immutables, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Struct_Type) + ((t->name_pos + 1 - mzFLEX_DELTA) * sizeof(Scheme_Struct_Type *)))); +# endif +#endif } static int mark_struct_type_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Struct_Type *t = (Scheme_Struct_Type *)p; int i; @@ -143,10 +183,15 @@ static int mark_struct_type_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(t->guard, gc); gcFIXUP2(t->immutables, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Struct_Type) + ((t->name_pos + 1 - mzFLEX_DELTA) * sizeof(Scheme_Struct_Type *)))); +# endif +#endif } #define mark_struct_type_val_IS_ATOMIC 0 @@ -154,26 +199,41 @@ static int mark_struct_type_val_FIXUP(void *p, struct NewGC *gc) { static int mark_struct_property_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Struct_Property)); +#else + return 0; +#endif } static int mark_struct_property_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Struct_Property *i = (Scheme_Struct_Property *)p; gcMARK2(i->name, gc); gcMARK2(i->guard, gc); gcMARK2(i->supers, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Struct_Property)); +# endif +#endif } static int mark_struct_property_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Struct_Property *i = (Scheme_Struct_Property *)p; gcFIXUP2(i->name, gc); gcFIXUP2(i->guard, gc); gcFIXUP2(i->supers, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Struct_Property)); +# endif +#endif } #define mark_struct_property_IS_ATOMIC 0 @@ -181,28 +241,43 @@ static int mark_struct_property_FIXUP(void *p, struct NewGC *gc) { static int mark_wrapped_evt_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Wrapped_Evt)); +#else + return 0; +#endif } static int mark_wrapped_evt_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Wrapped_Evt *ww = (Wrapped_Evt *)p; gcMARK2(ww->evt, gc); gcMARK2(ww->wrapper, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Wrapped_Evt)); +# endif +#endif } static int mark_wrapped_evt_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Wrapped_Evt *ww = (Wrapped_Evt *)p; gcFIXUP2(ww->evt, gc); gcFIXUP2(ww->wrapper, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Wrapped_Evt)); +# endif +#endif } #define mark_wrapped_evt_IS_ATOMIC 0 @@ -210,26 +285,41 @@ static int mark_wrapped_evt_FIXUP(void *p, struct NewGC *gc) { static int mark_nack_guard_evt_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Nack_Guard_Evt)); +#else + return 0; +#endif } static int mark_nack_guard_evt_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Nack_Guard_Evt *nw = (Nack_Guard_Evt *)p; gcMARK2(nw->maker, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Nack_Guard_Evt)); +# endif +#endif } static int mark_nack_guard_evt_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Nack_Guard_Evt *nw = (Nack_Guard_Evt *)p; gcFIXUP2(nw->maker, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Nack_Guard_Evt)); +# endif +#endif } #define mark_nack_guard_evt_IS_ATOMIC 0 @@ -237,30 +327,45 @@ static int mark_nack_guard_evt_FIXUP(void *p, struct NewGC *gc) { static int mark_active_replace_evt_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Active_Replace_Evt)); +#else + return 0; +#endif } static int mark_active_replace_evt_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Active_Replace_Evt *a = (Active_Replace_Evt *)p; gcMARK2(a->syncing, gc); gcMARK2(a->wrapper, gc); gcMARK2(a->orig, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Active_Replace_Evt)); +# endif +#endif } static int mark_active_replace_evt_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Active_Replace_Evt *a = (Active_Replace_Evt *)p; gcFIXUP2(a->syncing, gc); gcFIXUP2(a->wrapper, gc); gcFIXUP2(a->orig, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Active_Replace_Evt)); +# endif +#endif } #define mark_active_replace_evt_IS_ATOMIC 0 @@ -268,11 +373,15 @@ static int mark_active_replace_evt_FIXUP(void *p, struct NewGC *gc) { static int mark_chaperone_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Chaperone)); +#else + return 0; +#endif } static int mark_chaperone_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Chaperone *px = (Scheme_Chaperone *)p; gcMARK2(px->val, gc); @@ -280,11 +389,17 @@ static int mark_chaperone_MARK(void *p, struct NewGC *gc) { gcMARK2(px->props, gc); gcMARK2(px->redirects, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Chaperone)); +# endif +#endif } static int mark_chaperone_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Chaperone *px = (Scheme_Chaperone *)p; gcFIXUP2(px->val, gc); @@ -292,8 +407,13 @@ static int mark_chaperone_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(px->props, gc); gcFIXUP2(px->redirects, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Chaperone)); +# endif +#endif } #define mark_chaperone_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_syntax.inc b/racket/src/racket/src/mzmark_syntax.inc index a9dbae7105..a0d593f777 100644 --- a/racket/src/racket/src/mzmark_syntax.inc +++ b/racket/src/racket/src/mzmark_syntax.inc @@ -1,22 +1,37 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_srcloc_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Stx_Srcloc)); +#else + return 0; +#endif } static int mark_srcloc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Stx_Srcloc *s = (Scheme_Stx_Srcloc *)p; gcMARK2(s->src, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Stx_Srcloc)); +# endif +#endif } static int mark_srcloc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Stx_Srcloc *s = (Scheme_Stx_Srcloc *)p; gcFIXUP2(s->src, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Stx_Srcloc)); +# endif +#endif } #define mark_srcloc_IS_ATOMIC 0 @@ -24,15 +39,19 @@ static int mark_srcloc_FIXUP(void *p, struct NewGC *gc) { static int mark_scope_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Scope *m = (Scheme_Scope *)p; int for_multi = SCHEME_SCOPE_HAS_OWNER(m); - return (for_multi ? gcBYTES_TO_WORDS(sizeof(Scheme_Scope_With_Owner)) : gcBYTES_TO_WORDS(sizeof(Scheme_Scope))); +#else + return 0; +#endif } static int mark_scope_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Scope *m = (Scheme_Scope *)p; int for_multi = SCHEME_SCOPE_HAS_OWNER(m); gcMARK2(m->bindings, gc); @@ -40,13 +59,19 @@ static int mark_scope_MARK(void *p, struct NewGC *gc) { gcMARK2(((Scheme_Scope_With_Owner *)m)->owner_multi_scope, gc); gcMARK2(((Scheme_Scope_With_Owner *)m)->phase, gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return (for_multi ? gcBYTES_TO_WORDS(sizeof(Scheme_Scope_With_Owner)) : gcBYTES_TO_WORDS(sizeof(Scheme_Scope))); +# endif +#endif } static int mark_scope_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Scope *m = (Scheme_Scope *)p; int for_multi = SCHEME_SCOPE_HAS_OWNER(m); gcFIXUP2(m->bindings, gc); @@ -54,10 +79,15 @@ static int mark_scope_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(((Scheme_Scope_With_Owner *)m)->owner_multi_scope, gc); gcFIXUP2(((Scheme_Scope_With_Owner *)m)->phase, gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return (for_multi ? gcBYTES_TO_WORDS(sizeof(Scheme_Scope_With_Owner)) : gcBYTES_TO_WORDS(sizeof(Scheme_Scope))); +# endif +#endif } #define mark_scope_IS_ATOMIC 0 @@ -65,24 +95,39 @@ static int mark_scope_FIXUP(void *p, struct NewGC *gc) { static int mark_scope_table_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Scope_Table)); +#else + return 0; +#endif } static int mark_scope_table_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Scope_Table *m = (Scheme_Scope_Table *)p; gcMARK2(m->simple_scopes, gc); gcMARK2(m->multi_scopes, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Scope_Table)); +# endif +#endif } static int mark_scope_table_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Scope_Table *m = (Scheme_Scope_Table *)p; gcFIXUP2(m->simple_scopes, gc); gcFIXUP2(m->multi_scopes, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Scope_Table)); +# endif +#endif } #define mark_scope_table_IS_ATOMIC 0 @@ -90,26 +135,41 @@ static int mark_scope_table_FIXUP(void *p, struct NewGC *gc) { static int mark_propagate_table_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Propagate_Table)); +#else + return 0; +#endif } static int mark_propagate_table_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Propagate_Table *m = (Scheme_Propagate_Table *)p; mark_scope_table_MARK(&m->st, gc); gcMARK2(m->prev, gc); gcMARK2(m->phase_shift, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Propagate_Table)); +# endif +#endif } static int mark_propagate_table_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Propagate_Table *m = (Scheme_Propagate_Table *)p; mark_scope_table_FIXUP(&m->st, gc); gcFIXUP2(m->prev, gc); gcFIXUP2(m->phase_shift, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Propagate_Table)); +# endif +#endif } #define mark_propagate_table_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_thread.inc b/racket/src/racket/src/mzmark_thread.inc index b71777d3ed..4947d48025 100644 --- a/racket/src/racket/src/mzmark_thread.inc +++ b/racket/src/racket/src/mzmark_thread.inc @@ -1,12 +1,16 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_parameterization_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS((sizeof(Scheme_Parameterization) + ((max_configs - mzFLEX_DELTA) * sizeof(Scheme_Object*)))); +#else + return 0; +#endif } static int mark_parameterization_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Parameterization *c = (Scheme_Parameterization *)p; int i; @@ -15,12 +19,18 @@ static int mark_parameterization_MARK(void *p, struct NewGC *gc) { } gcMARK2(c->extensions, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Parameterization) + ((max_configs - mzFLEX_DELTA) * sizeof(Scheme_Object*)))); +# endif +#endif } static int mark_parameterization_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Parameterization *c = (Scheme_Parameterization *)p; int i; @@ -29,9 +39,14 @@ static int mark_parameterization_FIXUP(void *p, struct NewGC *gc) { } gcFIXUP2(c->extensions, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Parameterization) + ((max_configs - mzFLEX_DELTA) * sizeof(Scheme_Object*)))); +# endif +#endif } #define mark_parameterization_IS_ATOMIC 0 @@ -39,24 +54,39 @@ static int mark_parameterization_FIXUP(void *p, struct NewGC *gc) { static int mark_config_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Config)); +#else + return 0; +#endif } static int mark_config_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Config *config = (Scheme_Config *)p; gcMARK2(config->ht, gc); gcMARK2(config->root, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Config)); +# endif +#endif } static int mark_config_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Config *config = (Scheme_Config *)p; gcFIXUP2(config->ht, gc); gcFIXUP2(config->root, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Config)); +# endif +#endif } #define mark_config_IS_ATOMIC 0 @@ -64,30 +94,45 @@ static int mark_config_FIXUP(void *p, struct NewGC *gc) { static int mark_will_executor_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(WillExecutor)); +#else + return 0; +#endif } static int mark_will_executor_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED WillExecutor *e = (WillExecutor *)p; gcMARK2(e->sema, gc); gcMARK2(e->first, gc); gcMARK2(e->last, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(WillExecutor)); +# endif +#endif } static int mark_will_executor_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED WillExecutor *e = (WillExecutor *)p; gcFIXUP2(e->sema, gc); gcFIXUP2(e->first, gc); gcFIXUP2(e->last, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(WillExecutor)); +# endif +#endif } #define mark_will_executor_val_IS_ATOMIC 0 @@ -95,11 +140,15 @@ static int mark_will_executor_val_FIXUP(void *p, struct NewGC *gc) { static int mark_custodian_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Custodian)); +#else + return 0; +#endif } static int mark_custodian_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Custodian *m = (Scheme_Custodian *)p; gcMARK2(m->boxes, gc); @@ -117,11 +166,17 @@ static int mark_custodian_val_MARK(void *p, struct NewGC *gc) { gcMARK2(m->cust_boxes, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Custodian)); +# endif +#endif } static int mark_custodian_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Custodian *m = (Scheme_Custodian *)p; gcFIXUP2(m->boxes, gc); @@ -139,8 +194,13 @@ static int mark_custodian_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(m->cust_boxes, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Custodian)); +# endif +#endif } #define mark_custodian_val_IS_ATOMIC 0 @@ -148,11 +208,15 @@ static int mark_custodian_val_FIXUP(void *p, struct NewGC *gc) { static int mark_custodian_box_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Custodian_Box)); +#else + return 0; +#endif } static int mark_custodian_box_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Custodian_Box *b = (Scheme_Custodian_Box *)p; int sd = ((Scheme_Custodian *)GC_resolve2(b->cust, gc))->shut_down; @@ -161,11 +225,17 @@ static int mark_custodian_box_val_MARK(void *p, struct NewGC *gc) { gcMARK2(b->v, gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Custodian_Box)); +# endif +#endif } static int mark_custodian_box_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Custodian_Box *b = (Scheme_Custodian_Box *)p; int sd = ((Scheme_Custodian *)GC_resolve2(b->cust, gc))->shut_down; @@ -174,8 +244,13 @@ static int mark_custodian_box_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(b->v, gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Custodian_Box)); +# endif +#endif } #define mark_custodian_box_val_IS_ATOMIC 0 @@ -183,26 +258,41 @@ static int mark_custodian_box_val_FIXUP(void *p, struct NewGC *gc) { static int mark_thread_hop_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Custodian_Hop)); +#else + return 0; +#endif } static int mark_thread_hop_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Thread_Custodian_Hop *hop = (Scheme_Thread_Custodian_Hop *)p; gcMARK2(hop->p, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Custodian_Hop)); +# endif +#endif } static int mark_thread_hop_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Thread_Custodian_Hop *hop = (Scheme_Thread_Custodian_Hop *)p; gcFIXUP2(hop->p, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Custodian_Hop)); +# endif +#endif } #define mark_thread_hop_IS_ATOMIC 0 @@ -210,11 +300,15 @@ static int mark_thread_hop_FIXUP(void *p, struct NewGC *gc) { static int mark_param_data_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(ParamData)); +#else + return 0; +#endif } static int mark_param_data_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED ParamData *d = (ParamData *)p; gcMARK2(d->key, gc); @@ -222,11 +316,17 @@ static int mark_param_data_MARK(void *p, struct NewGC *gc) { gcMARK2(d->extract_guard, gc); gcMARK2(d->defcell, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(ParamData)); +# endif +#endif } static int mark_param_data_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED ParamData *d = (ParamData *)p; gcFIXUP2(d->key, gc); @@ -234,8 +334,13 @@ static int mark_param_data_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(d->extract_guard, gc); gcFIXUP2(d->defcell, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(ParamData)); +# endif +#endif } #define mark_param_data_IS_ATOMIC 0 @@ -243,11 +348,15 @@ static int mark_param_data_FIXUP(void *p, struct NewGC *gc) { static int mark_will_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(ActiveWill)); +#else + return 0; +#endif } static int mark_will_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED ActiveWill *w = (ActiveWill *)p; gcMARK2(w->o, gc); @@ -255,11 +364,17 @@ static int mark_will_MARK(void *p, struct NewGC *gc) { gcMARK2(w->w, gc); gcMARK2(w->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(ActiveWill)); +# endif +#endif } static int mark_will_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED ActiveWill *w = (ActiveWill *)p; gcFIXUP2(w->o, gc); @@ -267,8 +382,13 @@ static int mark_will_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(w->w, gc); gcFIXUP2(w->next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(ActiveWill)); +# endif +#endif } #define mark_will_IS_ATOMIC 0 @@ -276,18 +396,33 @@ static int mark_will_FIXUP(void *p, struct NewGC *gc) { static int mark_evt_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Evt)); +#else + return 0; +#endif } static int mark_evt_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Evt)); +# endif +#endif } static int mark_evt_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Evt)); +# endif +#endif } #define mark_evt_IS_ATOMIC 1 @@ -295,11 +430,15 @@ static int mark_evt_FIXUP(void *p, struct NewGC *gc) { static int mark_syncing_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Syncing)); +#else + return 0; +#endif } static int mark_syncing_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Syncing *w = (Syncing *)p; gcMARK2(w->set, gc); @@ -310,11 +449,17 @@ static int mark_syncing_MARK(void *p, struct NewGC *gc) { gcMARK2(w->disable_break, gc); gcMARK2(w->thread, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Syncing)); +# endif +#endif } static int mark_syncing_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Syncing *w = (Syncing *)p; gcFIXUP2(w->set, gc); @@ -325,8 +470,13 @@ static int mark_syncing_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(w->disable_break, gc); gcFIXUP2(w->thread, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Syncing)); +# endif +#endif } #define mark_syncing_IS_ATOMIC 0 @@ -334,28 +484,43 @@ static int mark_syncing_FIXUP(void *p, struct NewGC *gc) { static int mark_evt_set_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Evt_Set)); +#else + return 0; +#endif } static int mark_evt_set_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Evt_Set *w = (Evt_Set *)p; gcMARK2(w->ws, gc); gcMARK2(w->argv, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Evt_Set)); +# endif +#endif } static int mark_evt_set_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Evt_Set *w = (Evt_Set *)p; gcFIXUP2(w->ws, gc); gcFIXUP2(w->argv, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Evt_Set)); +# endif +#endif } #define mark_evt_set_IS_ATOMIC 0 @@ -363,11 +528,15 @@ static int mark_evt_set_FIXUP(void *p, struct NewGC *gc) { static int mark_thread_set_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Set)); +#else + return 0; +#endif } static int mark_thread_set_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Thread_Set *ts = (Scheme_Thread_Set *)p; gcMARK2(ts->parent, gc); @@ -377,11 +546,17 @@ static int mark_thread_set_MARK(void *p, struct NewGC *gc) { gcMARK2(ts->search_start, gc); gcMARK2(ts->current, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Set)); +# endif +#endif } static int mark_thread_set_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Thread_Set *ts = (Scheme_Thread_Set *)p; gcFIXUP2(ts->parent, gc); @@ -391,8 +566,13 @@ static int mark_thread_set_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(ts->search_start, gc); gcFIXUP2(ts->current, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Thread_Set)); +# endif +#endif } #define mark_thread_set_IS_ATOMIC 0 @@ -400,26 +580,41 @@ static int mark_thread_set_FIXUP(void *p, struct NewGC *gc) { static int mark_thread_cell_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Thread_Cell)); +#else + return 0; +#endif } static int mark_thread_cell_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Thread_Cell *c = (Thread_Cell *)p; gcMARK2(c->def_val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Thread_Cell)); +# endif +#endif } static int mark_thread_cell_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Thread_Cell *c = (Thread_Cell *)p; gcFIXUP2(c->def_val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Thread_Cell)); +# endif +#endif } #define mark_thread_cell_IS_ATOMIC 0 @@ -427,28 +622,43 @@ static int mark_thread_cell_FIXUP(void *p, struct NewGC *gc) { static int mark_plumber_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Plumber)); +#else + return 0; +#endif } static int mark_plumber_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Plumber *pl = (Scheme_Plumber *)p; gcMARK2(pl->handles, gc); gcMARK2(pl->weak_handles, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Plumber)); +# endif +#endif } static int mark_plumber_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Plumber *pl = (Scheme_Plumber *)p; gcFIXUP2(pl->handles, gc); gcFIXUP2(pl->weak_handles, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Plumber)); +# endif +#endif } #define mark_plumber_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_type.inc b/racket/src/racket/src/mzmark_type.inc index a91c8c8d03..c8301ef6cf 100644 --- a/racket/src/racket/src/mzmark_type.inc +++ b/racket/src/racket/src/mzmark_type.inc @@ -1,30 +1,45 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int variable_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Bucket_With_Home)); +#else + return 0; +#endif } static int variable_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Bucket *b = (Scheme_Bucket *)p; gcMARK2(b->key, gc); gcMARK2(b->val, gc); gcMARK2(((Scheme_Bucket_With_Home *)b)->home_link, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Bucket_With_Home)); +# endif +#endif } static int variable_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Bucket *b = (Scheme_Bucket *)p; gcFIXUP2(b->key, gc); gcFIXUP2(b->val, gc); gcFIXUP2(((Scheme_Bucket_With_Home *)b)->home_link, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Bucket_With_Home)); +# endif +#endif } #define variable_obj_IS_ATOMIC 0 @@ -32,11 +47,15 @@ static int variable_obj_FIXUP(void *p, struct NewGC *gc) { static int module_var_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Module_Variable)); +#else + return 0; +#endif } static int module_var_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Module_Variable *mv = (Module_Variable *)p; gcMARK2(mv->modidx, gc); @@ -44,11 +63,17 @@ static int module_var_MARK(void *p, struct NewGC *gc) { gcMARK2(mv->insp, gc); gcMARK2(mv->shape, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Module_Variable)); +# endif +#endif } static int module_var_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Module_Variable *mv = (Module_Variable *)p; gcFIXUP2(mv->modidx, gc); @@ -56,8 +81,13 @@ static int module_var_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(mv->insp, gc); gcFIXUP2(mv->shape, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Module_Variable)); +# endif +#endif } #define module_var_IS_ATOMIC 0 @@ -65,28 +95,43 @@ static int module_var_FIXUP(void *p, struct NewGC *gc) { static int bucket_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Bucket)); +#else + return 0; +#endif } static int bucket_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Bucket *b = (Scheme_Bucket *)p; gcMARK2(b->key, gc); gcMARK2(b->val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Bucket)); +# endif +#endif } static int bucket_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Bucket *b = (Scheme_Bucket *)p; gcFIXUP2(b->key, gc); gcFIXUP2(b->val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Bucket)); +# endif +#endif } #define bucket_obj_IS_ATOMIC 0 @@ -94,18 +139,33 @@ static int bucket_obj_FIXUP(void *p, struct NewGC *gc) { static int local_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Local)); +#else + return 0; +#endif } static int local_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Local)); +# endif +#endif } static int local_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Local)); +# endif +#endif } #define local_obj_IS_ATOMIC 1 @@ -113,18 +173,33 @@ static int local_obj_FIXUP(void *p, struct NewGC *gc) { static int toplevel_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Toplevel)); +#else + return 0; +#endif } static int toplevel_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Toplevel)); +# endif +#endif } static int toplevel_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Toplevel)); +# endif +#endif } #define toplevel_obj_IS_ATOMIC 1 @@ -132,18 +207,33 @@ static int toplevel_obj_FIXUP(void *p, struct NewGC *gc) { static int quotesyntax_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Quote_Syntax)); +#else + return 0; +#endif } static int quotesyntax_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Quote_Syntax)); +# endif +#endif } static int quotesyntax_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Quote_Syntax)); +# endif +#endif } #define quotesyntax_obj_IS_ATOMIC 1 @@ -151,32 +241,47 @@ static int quotesyntax_obj_FIXUP(void *p, struct NewGC *gc) { static int cpointer_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS (SCHEME_CPTR_HAS_OFFSET(p) ? gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr)) : gcBYTES_TO_WORDS(sizeof(Scheme_Cptr))); +#else + return 0; +#endif } static int cpointer_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) { gcMARK2(SCHEME_CPTR_VAL(p), gc); } gcMARK2(SCHEME_CPTR_TYPE(p), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return (SCHEME_CPTR_HAS_OFFSET(p) ? gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr)) : gcBYTES_TO_WORDS(sizeof(Scheme_Cptr))); +# endif +#endif } static int cpointer_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) { gcFIXUP2(SCHEME_CPTR_VAL(p), gc); } gcFIXUP2(SCHEME_CPTR_TYPE(p), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return (SCHEME_CPTR_HAS_OFFSET(p) ? gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr)) : gcBYTES_TO_WORDS(sizeof(Scheme_Cptr))); +# endif +#endif } #define cpointer_obj_IS_ATOMIC 0 @@ -184,22 +289,37 @@ static int cpointer_obj_FIXUP(void *p, struct NewGC *gc) { static int twoptr_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +#else + return 0; +#endif } static int twoptr_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED gcMARK2(SCHEME_PTR1_VAL((Scheme_Object *)p), gc); gcMARK2(SCHEME_PTR2_VAL((Scheme_Object *)p), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } static int twoptr_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED gcFIXUP2(SCHEME_PTR1_VAL((Scheme_Object *)p), gc); gcFIXUP2(SCHEME_PTR2_VAL((Scheme_Object *)p), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } #define twoptr_obj_IS_ATOMIC 0 @@ -207,20 +327,35 @@ static int twoptr_obj_FIXUP(void *p, struct NewGC *gc) { static int iptr_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +#else + return 0; +#endif } static int iptr_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED gcMARK2(SCHEME_IPTR_VAL((Scheme_Object *)p), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } static int iptr_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED gcFIXUP2(SCHEME_IPTR_VAL((Scheme_Object *)p), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } #define iptr_obj_IS_ATOMIC 0 @@ -228,22 +363,37 @@ static int iptr_obj_FIXUP(void *p, struct NewGC *gc) { static int small_object_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Small_Object)); +#else + return 0; +#endif } static int small_object_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED gcMARK2(((Scheme_Small_Object *)p)->u.ptr_value, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Small_Object)); +# endif +#endif } static int small_object_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED gcFIXUP2(((Scheme_Small_Object *)p)->u.ptr_value, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Small_Object)); +# endif +#endif } #define small_object_IS_ATOMIC 0 @@ -251,18 +401,33 @@ static int small_object_FIXUP(void *p, struct NewGC *gc) { static int small_atomic_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Small_Object)); +#else + return 0; +#endif } static int small_atomic_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Small_Object)); +# endif +#endif } static int small_atomic_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Small_Object)); +# endif +#endif } #define small_atomic_obj_IS_ATOMIC 1 @@ -270,38 +435,53 @@ static int small_atomic_obj_FIXUP(void *p, struct NewGC *gc) { static int app_rec_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_App_Rec *r = (Scheme_App_Rec *)p; - return gcBYTES_TO_WORDS((sizeof(Scheme_App_Rec) + ((r->num_args + 1 - mzFLEX_DELTA) * sizeof(Scheme_Object *)) + ((r->num_args + 1) * sizeof(char)))); +#else + return 0; +#endif } static int app_rec_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_App_Rec *r = (Scheme_App_Rec *)p; int i = r->num_args + 1; while (i--) gcMARK2(r->args[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_App_Rec) + ((r->num_args + 1 - mzFLEX_DELTA) * sizeof(Scheme_Object *)) + ((r->num_args + 1) * sizeof(char)))); +# endif +#endif } static int app_rec_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_App_Rec *r = (Scheme_App_Rec *)p; int i = r->num_args + 1; while (i--) gcFIXUP2(r->args[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_App_Rec) + ((r->num_args + 1 - mzFLEX_DELTA) * sizeof(Scheme_Object *)) + ((r->num_args + 1) * sizeof(char)))); +# endif +#endif } #define app_rec_IS_ATOMIC 0 @@ -309,26 +489,41 @@ static int app_rec_FIXUP(void *p, struct NewGC *gc) { static int app2_rec_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_App2_Rec)); +#else + return 0; +#endif } static int app2_rec_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_App2_Rec *r = (Scheme_App2_Rec *)p; gcMARK2(r->rator, gc); gcMARK2(r->rand, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_App2_Rec)); +# endif +#endif } static int app2_rec_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_App2_Rec *r = (Scheme_App2_Rec *)p; gcFIXUP2(r->rator, gc); gcFIXUP2(r->rand, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_App2_Rec)); +# endif +#endif } #define app2_rec_IS_ATOMIC 0 @@ -336,28 +531,43 @@ static int app2_rec_FIXUP(void *p, struct NewGC *gc) { static int app3_rec_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_App3_Rec)); +#else + return 0; +#endif } static int app3_rec_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_App3_Rec *r = (Scheme_App3_Rec *)p; gcMARK2(r->rator, gc); gcMARK2(r->rand1, gc); gcMARK2(r->rand2, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_App3_Rec)); +# endif +#endif } static int app3_rec_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_App3_Rec *r = (Scheme_App3_Rec *)p; gcFIXUP2(r->rator, gc); gcFIXUP2(r->rand1, gc); gcFIXUP2(r->rand2, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_App3_Rec)); +# endif +#endif } #define app3_rec_IS_ATOMIC 0 @@ -365,35 +575,50 @@ static int app3_rec_FIXUP(void *p, struct NewGC *gc) { static int seq_rec_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Sequence *s = (Scheme_Sequence *)p; - return gcBYTES_TO_WORDS((sizeof(Scheme_Sequence) + ((s->count - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +#else + return 0; +#endif } static int seq_rec_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Sequence *s = (Scheme_Sequence *)p; int i = s->count; while (i--) gcMARK2(s->array[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Sequence) + ((s->count - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } static int seq_rec_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Sequence *s = (Scheme_Sequence *)p; int i = s->count; while (i--) gcFIXUP2(s->array[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Sequence) + ((s->count - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } #define seq_rec_IS_ATOMIC 0 @@ -401,30 +626,45 @@ static int seq_rec_FIXUP(void *p, struct NewGC *gc) { static int branch_rec_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Branch_Rec)); +#else + return 0; +#endif } static int branch_rec_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Branch_Rec *b = (Scheme_Branch_Rec *)p; gcMARK2(b->test, gc); gcMARK2(b->tbranch, gc); gcMARK2(b->fbranch, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Branch_Rec)); +# endif +#endif } static int branch_rec_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Branch_Rec *b = (Scheme_Branch_Rec *)p; gcFIXUP2(b->test, gc); gcFIXUP2(b->tbranch, gc); gcFIXUP2(b->fbranch, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Branch_Rec)); +# endif +#endif } #define branch_rec_IS_ATOMIC 0 @@ -432,11 +672,15 @@ static int branch_rec_FIXUP(void *p, struct NewGC *gc) { static int unclosed_proc_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Closure_Data)); +#else + return 0; +#endif } static int unclosed_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Closure_Data *d = (Scheme_Closure_Data *)p; gcMARK2(d->name, gc); @@ -448,11 +692,17 @@ static int unclosed_proc_MARK(void *p, struct NewGC *gc) { gcMARK2(d->context, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Closure_Data)); +# endif +#endif } static int unclosed_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Closure_Data *d = (Scheme_Closure_Data *)p; gcFIXUP2(d->name, gc); @@ -464,8 +714,13 @@ static int unclosed_proc_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(d->context, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Closure_Data)); +# endif +#endif } #define unclosed_proc_IS_ATOMIC 0 @@ -473,28 +728,43 @@ static int unclosed_proc_FIXUP(void *p, struct NewGC *gc) { static int let_value_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Let_Value)); +#else + return 0; +#endif } static int let_value_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Let_Value *l = (Scheme_Let_Value *)p; gcMARK2(l->value, gc); gcMARK2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_Value)); +# endif +#endif } static int let_value_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Let_Value *l = (Scheme_Let_Value *)p; gcFIXUP2(l->value, gc); gcFIXUP2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_Value)); +# endif +#endif } #define let_value_IS_ATOMIC 0 @@ -502,26 +772,41 @@ static int let_value_FIXUP(void *p, struct NewGC *gc) { static int let_void_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Let_Void)); +#else + return 0; +#endif } static int let_void_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Let_Void *l = (Scheme_Let_Void *)p; gcMARK2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_Void)); +# endif +#endif } static int let_void_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Let_Void *l = (Scheme_Let_Void *)p; gcFIXUP2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_Void)); +# endif +#endif } #define let_void_IS_ATOMIC 0 @@ -529,28 +814,43 @@ static int let_void_FIXUP(void *p, struct NewGC *gc) { static int letrec_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Letrec)); +#else + return 0; +#endif } static int letrec_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Letrec *l = (Scheme_Letrec *)p; gcMARK2(l->procs, gc); gcMARK2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Letrec)); +# endif +#endif } static int letrec_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Letrec *l = (Scheme_Letrec *)p; gcFIXUP2(l->procs, gc); gcFIXUP2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Letrec)); +# endif +#endif } #define letrec_IS_ATOMIC 0 @@ -558,28 +858,43 @@ static int letrec_FIXUP(void *p, struct NewGC *gc) { static int let_one_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Let_One)); +#else + return 0; +#endif } static int let_one_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Let_One *l = (Scheme_Let_One *)p; gcMARK2(l->value, gc); gcMARK2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_One)); +# endif +#endif } static int let_one_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Let_One *l = (Scheme_Let_One *)p; gcFIXUP2(l->value, gc); gcFIXUP2(l->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_One)); +# endif +#endif } #define let_one_IS_ATOMIC 0 @@ -587,30 +902,45 @@ static int let_one_FIXUP(void *p, struct NewGC *gc) { static int with_cont_mark_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_With_Continuation_Mark)); +#else + return 0; +#endif } static int with_cont_mark_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_With_Continuation_Mark *w = (Scheme_With_Continuation_Mark *)p; gcMARK2(w->key, gc); gcMARK2(w->val, gc); gcMARK2(w->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_With_Continuation_Mark)); +# endif +#endif } static int with_cont_mark_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_With_Continuation_Mark *w = (Scheme_With_Continuation_Mark *)p; gcFIXUP2(w->key, gc); gcFIXUP2(w->val, gc); gcFIXUP2(w->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_With_Continuation_Mark)); +# endif +#endif } #define with_cont_mark_IS_ATOMIC 0 @@ -618,11 +948,15 @@ static int with_cont_mark_FIXUP(void *p, struct NewGC *gc) { static int comp_let_value_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value)); +#else + return 0; +#endif } static int comp_let_value_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Compiled_Let_Value *c = (Scheme_Compiled_Let_Value *)p; gcMARK2(c->flags, gc); @@ -630,11 +964,17 @@ static int comp_let_value_MARK(void *p, struct NewGC *gc) { gcMARK2(c->body, gc); gcMARK2(c->names, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value)); +# endif +#endif } static int comp_let_value_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Compiled_Let_Value *c = (Scheme_Compiled_Let_Value *)p; gcFIXUP2(c->flags, gc); @@ -642,8 +982,13 @@ static int comp_let_value_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(c->body, gc); gcFIXUP2(c->names, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value)); +# endif +#endif } #define comp_let_value_IS_ATOMIC 0 @@ -651,26 +996,41 @@ static int comp_let_value_FIXUP(void *p, struct NewGC *gc) { static int let_header_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Let_Header)); +#else + return 0; +#endif } static int let_header_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Let_Header *h = (Scheme_Let_Header *)p; gcMARK2(h->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_Header)); +# endif +#endif } static int let_header_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Let_Header *h = (Scheme_Let_Header *)p; gcFIXUP2(h->body, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Let_Header)); +# endif +#endif } #define let_header_IS_ATOMIC 0 @@ -678,28 +1038,43 @@ static int let_header_FIXUP(void *p, struct NewGC *gc) { static int set_bang_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Set_Bang)); +#else + return 0; +#endif } static int set_bang_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Set_Bang *b = (Scheme_Set_Bang *)p; gcMARK2(b->var, gc); gcMARK2(b->val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Set_Bang)); +# endif +#endif } static int set_bang_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Set_Bang *b = (Scheme_Set_Bang *)p; gcFIXUP2(b->var, gc); gcFIXUP2(b->val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Set_Bang)); +# endif +#endif } #define set_bang_IS_ATOMIC 0 @@ -707,18 +1082,22 @@ static int set_bang_FIXUP(void *p, struct NewGC *gc) { static int prim_proc_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Primitive_Proc *prim = (Scheme_Primitive_Proc *)p; - return ((prim->pp.flags & SCHEME_PRIM_IS_CLOSURE) ? (gcBYTES_TO_WORDS(sizeof(Scheme_Primitive_Closure)) + ((Scheme_Primitive_Closure *)prim)->count - mzFLEX_DELTA) : ((prim->pp.flags & SCHEME_PRIM_IS_MULTI_RESULT) ? gcBYTES_TO_WORDS(sizeof(Scheme_Prim_W_Result_Arity)) : gcBYTES_TO_WORDS(sizeof(Scheme_Primitive_Proc)))); +#else + return 0; +#endif } static int prim_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Primitive_Proc *prim = (Scheme_Primitive_Proc *)p; gcMARK2(prim->name, gc); @@ -733,6 +1112,9 @@ static int prim_proc_MARK(void *p, struct NewGC *gc) { } } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return ((prim->pp.flags & SCHEME_PRIM_IS_CLOSURE) ? (gcBYTES_TO_WORDS(sizeof(Scheme_Primitive_Closure)) @@ -740,9 +1122,12 @@ static int prim_proc_MARK(void *p, struct NewGC *gc) { : ((prim->pp.flags & SCHEME_PRIM_IS_MULTI_RESULT) ? gcBYTES_TO_WORDS(sizeof(Scheme_Prim_W_Result_Arity)) : gcBYTES_TO_WORDS(sizeof(Scheme_Primitive_Proc)))); +# endif +#endif } static int prim_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Primitive_Proc *prim = (Scheme_Primitive_Proc *)p; gcFIXUP2(prim->name, gc); @@ -757,6 +1142,9 @@ static int prim_proc_FIXUP(void *p, struct NewGC *gc) { } } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return ((prim->pp.flags & SCHEME_PRIM_IS_CLOSURE) ? (gcBYTES_TO_WORDS(sizeof(Scheme_Primitive_Closure)) @@ -764,6 +1152,8 @@ static int prim_proc_FIXUP(void *p, struct NewGC *gc) { : ((prim->pp.flags & SCHEME_PRIM_IS_MULTI_RESULT) ? gcBYTES_TO_WORDS(sizeof(Scheme_Prim_W_Result_Arity)) : gcBYTES_TO_WORDS(sizeof(Scheme_Primitive_Proc)))); +# endif +#endif } #define prim_proc_IS_ATOMIC 0 @@ -771,17 +1161,21 @@ static int prim_proc_FIXUP(void *p, struct NewGC *gc) { static int closed_prim_proc_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Closed_Primitive_Proc *c = (Scheme_Closed_Primitive_Proc *)p; - return ((c->pp.flags & SCHEME_PRIM_IS_MULTI_RESULT) ? gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Prim_W_Result_Arity)) : ((c->mina == -2) ? gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Case_Primitive_Proc)) : gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Primitive_Proc)))); +#else + return 0; +#endif } static int closed_prim_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Closed_Primitive_Proc *c = (Scheme_Closed_Primitive_Proc *)p; gcMARK2(c->name, gc); @@ -790,15 +1184,21 @@ static int closed_prim_proc_MARK(void *p, struct NewGC *gc) { gcMARK2(((Scheme_Closed_Case_Primitive_Proc *)c)->cases, gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return ((c->pp.flags & SCHEME_PRIM_IS_MULTI_RESULT) ? gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Prim_W_Result_Arity)) : ((c->mina == -2) ? gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Case_Primitive_Proc)) : gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Primitive_Proc)))); +# endif +#endif } static int closed_prim_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Closed_Primitive_Proc *c = (Scheme_Closed_Primitive_Proc *)p; gcFIXUP2(c->name, gc); @@ -807,12 +1207,17 @@ static int closed_prim_proc_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(((Scheme_Closed_Case_Primitive_Proc *)c)->cases, gc); } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return ((c->pp.flags & SCHEME_PRIM_IS_MULTI_RESULT) ? gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Prim_W_Result_Arity)) : ((c->mina == -2) ? gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Case_Primitive_Proc)) : gcBYTES_TO_WORDS(sizeof(Scheme_Closed_Primitive_Proc)))); +# endif +#endif } #define closed_prim_proc_IS_ATOMIC 0 @@ -820,17 +1225,21 @@ static int closed_prim_proc_FIXUP(void *p, struct NewGC *gc) { static int scm_closure_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Closure *c = (Scheme_Closure *)p; int closure_size = (c->code ? ((Scheme_Closure_Data *)GC_resolve2(c->code, gc))->closure_size : 0); - return gcBYTES_TO_WORDS((sizeof(Scheme_Closure) + (closure_size - mzFLEX_DELTA) * sizeof(Scheme_Object *))); +#else + return 0; +#endif } static int scm_closure_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Closure *c = (Scheme_Closure *)p; int closure_size = (c->code ? ((Scheme_Closure_Data *)GC_resolve2(c->code, gc))->closure_size @@ -851,12 +1260,18 @@ static int scm_closure_MARK(void *p, struct NewGC *gc) { # include "mzclpf_post.inc" # undef CLOSURE_DATA_TYPE +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Closure) + (closure_size - mzFLEX_DELTA) * sizeof(Scheme_Object *))); +# endif +#endif } static int scm_closure_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Closure *c = (Scheme_Closure *)p; int closure_size = (c->code ? ((Scheme_Closure_Data *)GC_resolve2(c->code, gc))->closure_size @@ -872,9 +1287,14 @@ static int scm_closure_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(c->vals[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Closure) + (closure_size - mzFLEX_DELTA) * sizeof(Scheme_Object *))); +# endif +#endif } #define scm_closure_IS_ATOMIC 0 @@ -882,14 +1302,18 @@ static int scm_closure_FIXUP(void *p, struct NewGC *gc) { static int case_closure_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Case_Lambda *c = (Scheme_Case_Lambda *)p; - return gcBYTES_TO_WORDS((sizeof(Scheme_Case_Lambda) + ((c->count - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +#else + return 0; +#endif } static int case_closure_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Case_Lambda *c = (Scheme_Case_Lambda *)p; int i; @@ -901,12 +1325,18 @@ static int case_closure_MARK(void *p, struct NewGC *gc) { gcMARK2(c->native_code, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Case_Lambda) + ((c->count - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } static int case_closure_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Case_Lambda *c = (Scheme_Case_Lambda *)p; int i; @@ -918,9 +1348,14 @@ static int case_closure_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(c->native_code, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Case_Lambda) + ((c->count - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } #define case_closure_IS_ATOMIC 0 @@ -928,11 +1363,15 @@ static int case_closure_FIXUP(void *p, struct NewGC *gc) { static int cont_proc_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Cont)); +#else + return 0; +#endif } static int cont_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Cont *c = (Scheme_Cont *)p; gcMARK2(c->dw, gc); @@ -971,11 +1410,17 @@ static int cont_proc_MARK(void *p, struct NewGC *gc) { gcMARK2(c->extra_marks, gc); gcMARK2(c->shortcut_prompt, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont)); +# endif +#endif } static int cont_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Cont *c = (Scheme_Cont *)p; gcFIXUP2(c->dw, gc); @@ -1014,8 +1459,13 @@ static int cont_proc_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(c->extra_marks, gc); gcFIXUP2(c->shortcut_prompt, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont)); +# endif +#endif } #define cont_proc_IS_ATOMIC 0 @@ -1023,26 +1473,41 @@ static int cont_proc_FIXUP(void *p, struct NewGC *gc) { static int cont_jmp_proc_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Jmp)); +#else + return 0; +#endif } static int cont_jmp_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Cont_Jmp *c = (Scheme_Cont_Jmp *)p; MARK_jmpup(&c->buf, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Jmp)); +# endif +#endif } static int cont_jmp_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Cont_Jmp *c = (Scheme_Cont_Jmp *)p; FIXUP_jmpup(&c->buf, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Jmp)); +# endif +#endif } #define cont_jmp_proc_IS_ATOMIC 0 @@ -1050,11 +1515,15 @@ static int cont_jmp_proc_FIXUP(void *p, struct NewGC *gc) { static int meta_cont_proc_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Meta_Continuation)); +#else + return 0; +#endif } static int meta_cont_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Meta_Continuation *c = (Scheme_Meta_Continuation *)p; gcMARK2(c->prompt_tag, gc); @@ -1063,11 +1532,17 @@ static int meta_cont_proc_MARK(void *p, struct NewGC *gc) { gcMARK2(c->cont_mark_stack_copied, gc); gcMARK2(c->cont, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Meta_Continuation)); +# endif +#endif } static int meta_cont_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Meta_Continuation *c = (Scheme_Meta_Continuation *)p; gcFIXUP2(c->prompt_tag, gc); @@ -1076,8 +1551,13 @@ static int meta_cont_proc_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(c->cont_mark_stack_copied, gc); gcFIXUP2(c->cont, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Meta_Continuation)); +# endif +#endif } #define meta_cont_proc_IS_ATOMIC 0 @@ -1085,11 +1565,15 @@ static int meta_cont_proc_FIXUP(void *p, struct NewGC *gc) { static int mark_dyn_wind_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Dynamic_Wind)); +#else + return 0; +#endif } static int mark_dyn_wind_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Dynamic_Wind *dw = (Scheme_Dynamic_Wind *)p; gcMARK2(dw->id, gc); @@ -1099,11 +1583,17 @@ static int mark_dyn_wind_MARK(void *p, struct NewGC *gc) { MARK_stack_state(&dw->envss, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Dynamic_Wind)); +# endif +#endif } static int mark_dyn_wind_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Dynamic_Wind *dw = (Scheme_Dynamic_Wind *)p; gcFIXUP2(dw->id, gc); @@ -1113,8 +1603,13 @@ static int mark_dyn_wind_FIXUP(void *p, struct NewGC *gc) { FIXUP_stack_state(&dw->envss, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Dynamic_Wind)); +# endif +#endif } #define mark_dyn_wind_IS_ATOMIC 0 @@ -1122,30 +1617,45 @@ static int mark_dyn_wind_FIXUP(void *p, struct NewGC *gc) { static int mark_overflow_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Overflow)); +#else + return 0; +#endif } static int mark_overflow_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Overflow *o = (Scheme_Overflow *)p; gcMARK2(o->prev, gc); gcMARK2(o->jmp, gc); gcMARK2(o->id, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Overflow)); +# endif +#endif } static int mark_overflow_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Overflow *o = (Scheme_Overflow *)p; gcFIXUP2(o->prev, gc); gcFIXUP2(o->jmp, gc); gcFIXUP2(o->id, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Overflow)); +# endif +#endif } #define mark_overflow_IS_ATOMIC 0 @@ -1153,26 +1663,41 @@ static int mark_overflow_FIXUP(void *p, struct NewGC *gc) { static int mark_overflow_jmp_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Overflow_Jmp)); +#else + return 0; +#endif } static int mark_overflow_jmp_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Overflow_Jmp *o = (Scheme_Overflow_Jmp *)p; MARK_jmpup(&o->cont, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Overflow_Jmp)); +# endif +#endif } static int mark_overflow_jmp_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Overflow_Jmp *o = (Scheme_Overflow_Jmp *)p; FIXUP_jmpup(&o->cont, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Overflow_Jmp)); +# endif +#endif } #define mark_overflow_jmp_IS_ATOMIC 0 @@ -1180,11 +1705,15 @@ static int mark_overflow_jmp_FIXUP(void *p, struct NewGC *gc) { static int escaping_cont_proc_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Escaping_Cont)); +#else + return 0; +#endif } static int escaping_cont_proc_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Escaping_Cont *c = (Scheme_Escaping_Cont *)p; #ifdef MZ_USE_JIT @@ -1194,11 +1723,17 @@ static int escaping_cont_proc_MARK(void *p, struct NewGC *gc) { gcMARK2(c->barrier_prompt, gc); MARK_stack_state(&c->envss, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Escaping_Cont)); +# endif +#endif } static int escaping_cont_proc_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Escaping_Cont *c = (Scheme_Escaping_Cont *)p; #ifdef MZ_USE_JIT @@ -1208,8 +1743,13 @@ static int escaping_cont_proc_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(c->barrier_prompt, gc); FIXUP_stack_state(&c->envss, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Escaping_Cont)); +# endif +#endif } #define escaping_cont_proc_IS_ATOMIC 0 @@ -1217,15 +1757,19 @@ static int escaping_cont_proc_FIXUP(void *p, struct NewGC *gc) { static int bignum_obj_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Bignum *b = (Scheme_Bignum *)p; - return ((!SCHEME_BIGINLINE(b)) ? gcBYTES_TO_WORDS(sizeof(Scheme_Bignum)) : gcBYTES_TO_WORDS(sizeof(Small_Bignum))); +#else + return 0; +#endif } static int bignum_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Bignum *b = (Scheme_Bignum *)p; if (!SCHEME_BIGINLINE(b)) { @@ -1234,13 +1778,19 @@ static int bignum_obj_MARK(void *p, struct NewGC *gc) { } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return ((!SCHEME_BIGINLINE(b)) ? gcBYTES_TO_WORDS(sizeof(Scheme_Bignum)) : gcBYTES_TO_WORDS(sizeof(Small_Bignum))); +# endif +#endif } static int bignum_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Bignum *b = (Scheme_Bignum *)p; if (!SCHEME_BIGINLINE(b)) { @@ -1249,10 +1799,15 @@ static int bignum_obj_FIXUP(void *p, struct NewGC *gc) { b->digits = ((Small_Bignum *)GC_fixup_self(b))->v; } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return ((!SCHEME_BIGINLINE(b)) ? gcBYTES_TO_WORDS(sizeof(Scheme_Bignum)) : gcBYTES_TO_WORDS(sizeof(Small_Bignum))); +# endif +#endif } #define bignum_obj_IS_ATOMIC 0 @@ -1260,28 +1815,43 @@ static int bignum_obj_FIXUP(void *p, struct NewGC *gc) { static int rational_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Rational)); +#else + return 0; +#endif } static int rational_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Rational *r = (Scheme_Rational *)p; gcMARK2(r->num, gc); gcMARK2(r->denom, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Rational)); +# endif +#endif } static int rational_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Rational *r = (Scheme_Rational *)p; gcFIXUP2(r->num, gc); gcFIXUP2(r->denom, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Rational)); +# endif +#endif } #define rational_obj_IS_ATOMIC 0 @@ -1289,30 +1859,45 @@ static int rational_obj_FIXUP(void *p, struct NewGC *gc) { static int float_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS #ifdef MZ_USE_SINGLE_FLOATS gcBYTES_TO_WORDS(sizeof(Scheme_Float)); #else 0; #endif +#else + return 0; +#endif } static int float_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return #ifdef MZ_USE_SINGLE_FLOATS gcBYTES_TO_WORDS(sizeof(Scheme_Float)); #else 0; #endif +# endif +#endif } static int float_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return #ifdef MZ_USE_SINGLE_FLOATS gcBYTES_TO_WORDS(sizeof(Scheme_Float)); #else 0; #endif +# endif +#endif } #define float_obj_IS_ATOMIC 1 @@ -1320,18 +1905,33 @@ static int float_obj_FIXUP(void *p, struct NewGC *gc) { static int double_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Double)); +#else + return 0; +#endif } static int double_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Double)); +# endif +#endif } static int double_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Double)); +# endif +#endif } #define double_obj_IS_ATOMIC 1 @@ -1340,18 +1940,33 @@ static int double_obj_FIXUP(void *p, struct NewGC *gc) { #ifdef MZ_LONG_DOUBLE static int long_double_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Long_Double)); +#else + return 0; +#endif } static int long_double_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Long_Double)); +# endif +#endif } static int long_double_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Long_Double)); +# endif +#endif } #define long_double_obj_IS_ATOMIC 1 @@ -1359,22 +1974,37 @@ static int long_double_obj_FIXUP(void *p, struct NewGC *gc) { #else static int long_double_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Long_Double)); +#else + return 0; +#endif } static int long_double_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Long_Double *ld = (Scheme_Long_Double *)p; gcMARK2(ld->printed_form, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Long_Double)); +# endif +#endif } static int long_double_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Long_Double *ld = (Scheme_Long_Double *)p; gcFIXUP2(ld->printed_form, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Long_Double)); +# endif +#endif } #define long_double_obj_IS_ATOMIC 0 @@ -1383,28 +2013,43 @@ static int long_double_obj_FIXUP(void *p, struct NewGC *gc) { #endif static int complex_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Complex)); +#else + return 0; +#endif } static int complex_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Complex *c = (Scheme_Complex *)p; gcMARK2(c->r, gc); gcMARK2(c->i, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Complex)); +# endif +#endif } static int complex_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Complex *c = (Scheme_Complex *)p; gcFIXUP2(c->r, gc); gcFIXUP2(c->i, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Complex)); +# endif +#endif } #define complex_obj_IS_ATOMIC 0 @@ -1412,24 +2057,39 @@ static int complex_obj_FIXUP(void *p, struct NewGC *gc) { static int string_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +#else + return 0; +#endif } static int string_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcMARK2(SCHEME_CHAR_STR_VAL(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } static int string_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcFIXUP2(SCHEME_CHAR_STR_VAL(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } #define string_obj_IS_ATOMIC 0 @@ -1437,24 +2097,39 @@ static int string_obj_FIXUP(void *p, struct NewGC *gc) { static int bstring_obj_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +#else + return 0; +#endif } static int bstring_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcMARK2(SCHEME_BYTE_STR_VAL(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } static int bstring_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcFIXUP2(SCHEME_BYTE_STR_VAL(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } #define bstring_obj_IS_ATOMIC 0 @@ -1462,24 +2137,33 @@ static int bstring_obj_FIXUP(void *p, struct NewGC *gc) { static int symbol_obj_SIZE(void *p, struct NewGC *gc) { - Scheme_Symbol *s = (Scheme_Symbol *)p; - - return - gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + s->len + 1 - mzFLEX4_DELTA); +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS + gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + ((Scheme_Symbol *)p)->len + 1 - mzFLEX4_DELTA); +#else + return 0; +#endif } static int symbol_obj_MARK(void *p, struct NewGC *gc) { - Scheme_Symbol *s = (Scheme_Symbol *)p; - +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return - gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + s->len + 1 - mzFLEX4_DELTA); + gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + ((Scheme_Symbol *)p)->len + 1 - mzFLEX4_DELTA); +# endif +#endif } static int symbol_obj_FIXUP(void *p, struct NewGC *gc) { - Scheme_Symbol *s = (Scheme_Symbol *)p; - +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return - gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + s->len + 1 - mzFLEX4_DELTA); + gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + ((Scheme_Symbol *)p)->len + 1 - mzFLEX4_DELTA); +# endif +#endif } #define symbol_obj_IS_ATOMIC 1 @@ -1487,28 +2171,43 @@ static int symbol_obj_FIXUP(void *p, struct NewGC *gc) { static int cons_cell_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +#else + return 0; +#endif } static int cons_cell_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcMARK2(SCHEME_CAR(o), gc); gcMARK2(SCHEME_CDR(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } static int cons_cell_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcFIXUP2(SCHEME_CAR(o), gc); gcFIXUP2(SCHEME_CDR(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } #define cons_cell_IS_ATOMIC 0 @@ -1516,35 +2215,50 @@ static int cons_cell_FIXUP(void *p, struct NewGC *gc) { static int vector_obj_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Vector *vec = (Scheme_Vector *)p; - return gcBYTES_TO_WORDS((sizeof(Scheme_Vector) + ((vec->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +#else + return 0; +#endif } static int vector_obj_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Vector *vec = (Scheme_Vector *)p; int i; for (i = vec->size; i--; ) gcMARK2(vec->els[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Vector) + ((vec->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } static int vector_obj_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Vector *vec = (Scheme_Vector *)p; int i; for (i = vec->size; i--; ) gcFIXUP2(vec->els[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Vector) + ((vec->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } #define vector_obj_IS_ATOMIC 0 @@ -1552,27 +2266,36 @@ static int vector_obj_FIXUP(void *p, struct NewGC *gc) { static int fxvector_obj_SIZE(void *p, struct NewGC *gc) { - Scheme_Vector *vec = (Scheme_Vector *)p; - - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS((sizeof(Scheme_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); + + ((((Scheme_Vector *)p)->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +#else + return 0; +#endif } static int fxvector_obj_MARK(void *p, struct NewGC *gc) { - Scheme_Vector *vec = (Scheme_Vector *)p; - +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); + + ((((Scheme_Vector *)p)->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } static int fxvector_obj_FIXUP(void *p, struct NewGC *gc) { - Scheme_Vector *vec = (Scheme_Vector *)p; - +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); + + ((((Scheme_Vector *)p)->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); +# endif +#endif } #define fxvector_obj_IS_ATOMIC 1 @@ -1580,27 +2303,36 @@ static int fxvector_obj_FIXUP(void *p, struct NewGC *gc) { static int flvector_obj_SIZE(void *p, struct NewGC *gc) { - Scheme_Double_Vector *vec = (Scheme_Double_Vector *)p; - - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS((sizeof(Scheme_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(double)))); + + ((((Scheme_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(double)))); +#else + return 0; +#endif } static int flvector_obj_MARK(void *p, struct NewGC *gc) { - Scheme_Double_Vector *vec = (Scheme_Double_Vector *)p; - +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(double)))); + + ((((Scheme_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(double)))); +# endif +#endif } static int flvector_obj_FIXUP(void *p, struct NewGC *gc) { - Scheme_Double_Vector *vec = (Scheme_Double_Vector *)p; - +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(double)))); + + ((((Scheme_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(double)))); +# endif +#endif } #define flvector_obj_IS_ATOMIC 1 @@ -1609,27 +2341,36 @@ static int flvector_obj_FIXUP(void *p, struct NewGC *gc) { #ifdef MZ_LONG_DOUBLE static int extflvector_obj_SIZE(void *p, struct NewGC *gc) { - Scheme_Long_Double_Vector *vec = (Scheme_Long_Double_Vector *)p; - - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS((sizeof(Scheme_Long_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(long double)))); + + ((((Scheme_Long_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(long double)))); +#else + return 0; +#endif } static int extflvector_obj_MARK(void *p, struct NewGC *gc) { - Scheme_Long_Double_Vector *vec = (Scheme_Long_Double_Vector *)p; - +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Long_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(long double)))); + + ((((Scheme_Long_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(long double)))); +# endif +#endif } static int extflvector_obj_FIXUP(void *p, struct NewGC *gc) { - Scheme_Long_Double_Vector *vec = (Scheme_Long_Double_Vector *)p; - +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Long_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(long double)))); + + ((((Scheme_Long_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(long double)))); +# endif +#endif } #define extflvector_obj_IS_ATOMIC 1 @@ -1638,11 +2379,15 @@ static int extflvector_obj_FIXUP(void *p, struct NewGC *gc) { #endif static int input_port_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Input_Port)); +#else + return 0; +#endif } static int input_port_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Input_Port *ip = (Scheme_Input_Port *)p; gcMARK2(ip->p.position_redirect, gc); @@ -1668,11 +2413,17 @@ static int input_port_MARK(void *p, struct NewGC *gc) { gcMARK2(ip->bufwidths, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Input_Port)); +# endif +#endif } static int input_port_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Input_Port *ip = (Scheme_Input_Port *)p; gcFIXUP2(ip->p.position_redirect, gc); @@ -1698,8 +2449,13 @@ static int input_port_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(ip->bufwidths, gc); #endif +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Input_Port)); +# endif +#endif } #define input_port_IS_ATOMIC 0 @@ -1707,11 +2463,15 @@ static int input_port_FIXUP(void *p, struct NewGC *gc) { static int output_port_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Output_Port)); +#else + return 0; +#endif } static int output_port_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Output_Port *op = (Scheme_Output_Port *)p; gcMARK2(op->p.position_redirect, gc); @@ -1725,11 +2485,17 @@ static int output_port_MARK(void *p, struct NewGC *gc) { gcMARK2(op->mref, gc); gcMARK2(op->input_half, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Output_Port)); +# endif +#endif } static int output_port_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Output_Port *op = (Scheme_Output_Port *)p; gcFIXUP2(op->p.position_redirect, gc); @@ -1743,8 +2509,13 @@ static int output_port_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(op->mref, gc); gcFIXUP2(op->input_half, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Output_Port)); +# endif +#endif } #define output_port_IS_ATOMIC 0 @@ -1753,18 +2524,33 @@ static int output_port_FIXUP(void *p, struct NewGC *gc) { static int syntax_compiler_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +#else + return 0; +#endif } static int syntax_compiler_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } static int syntax_compiler_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } #define syntax_compiler_IS_ATOMIC 1 @@ -1772,11 +2558,15 @@ static int syntax_compiler_FIXUP(void *p, struct NewGC *gc) { static int thread_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Thread)); +#else + return 0; +#endif } static int thread_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Thread *pr = (Scheme_Thread *)p; gcMARK2(pr->next, gc); @@ -1864,8 +2654,6 @@ static int thread_val_MARK(void *p, struct NewGC *gc) { gcMARK2(pr->self_for_proc_chaperone, gc); - gcMARK2(pr->list_stack, gc); - gcMARK2(pr->kill_data, gc); gcMARK2(pr->private_kill_data, gc); gcMARK2(pr->private_kill_next, gc); @@ -1900,11 +2688,17 @@ static int thread_val_MARK(void *p, struct NewGC *gc) { } } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Thread)); +# endif +#endif } static int thread_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Thread *pr = (Scheme_Thread *)p; gcFIXUP2(pr->next, gc); @@ -1992,8 +2786,6 @@ static int thread_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(pr->self_for_proc_chaperone, gc); - gcFIXUP2(pr->list_stack, gc); - gcFIXUP2(pr->kill_data, gc); gcFIXUP2(pr->private_kill_data, gc); gcFIXUP2(pr->private_kill_next, gc); @@ -2028,8 +2820,13 @@ static int thread_val_FIXUP(void *p, struct NewGC *gc) { } } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Thread)); +# endif +#endif } #define thread_val_IS_ATOMIC 0 @@ -2037,12 +2834,16 @@ static int thread_val_FIXUP(void *p, struct NewGC *gc) { static int runstack_val_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS intptr_t *s = (intptr_t *)p; - return s[1]; +#else + return 0; +#endif } static int runstack_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED intptr_t *s = (intptr_t *)p; void **a, **b; a = (void **)s + 5 + s[2]; @@ -2051,11 +2852,17 @@ static int runstack_val_MARK(void *p, struct NewGC *gc) { gcMARK2(*a, gc); a++; } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return s[1]; +# endif +#endif } static int runstack_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED intptr_t *s = (intptr_t *)p; void **a, **b; a = (void **)s + 5 + s[2]; @@ -2079,8 +2886,13 @@ static int runstack_val_FIXUP(void *p, struct NewGC *gc) { *a = RUNSTACK_ZERO_VAL; a++; } +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return s[1]; +# endif +#endif } #define runstack_val_IS_ATOMIC 0 @@ -2088,30 +2900,45 @@ static int runstack_val_FIXUP(void *p, struct NewGC *gc) { static int prompt_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Prompt)); +#else + return 0; +#endif } static int prompt_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Prompt *pr = (Scheme_Prompt *)p; gcMARK2(pr->boundary_overflow_id, gc); if (!GC_merely_accounting()) gcMARK2(pr->runstack_boundary_start, gc); gcMARK2(pr->tag, gc); gcMARK2(pr->id, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Prompt)); +# endif +#endif } static int prompt_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Prompt *pr = (Scheme_Prompt *)p; gcFIXUP2(pr->boundary_overflow_id, gc); if (!GC_merely_accounting()) gcFIXUP2(pr->runstack_boundary_start, gc); gcFIXUP2(pr->tag, gc); gcFIXUP2(pr->id, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Prompt)); +# endif +#endif } #define prompt_val_IS_ATOMIC 0 @@ -2119,26 +2946,41 @@ static int prompt_val_FIXUP(void *p, struct NewGC *gc) { static int cont_mark_set_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Mark_Set)); +#else + return 0; +#endif } static int cont_mark_set_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Cont_Mark_Set *s = (Scheme_Cont_Mark_Set *)p; gcMARK2(s->chain, gc); gcMARK2(s->native_stack_trace, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Mark_Set)); +# endif +#endif } static int cont_mark_set_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Cont_Mark_Set *s = (Scheme_Cont_Mark_Set *)p; gcFIXUP2(s->chain, gc); gcFIXUP2(s->native_stack_trace, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Mark_Set)); +# endif +#endif } #define cont_mark_set_val_IS_ATOMIC 0 @@ -2146,28 +2988,43 @@ static int cont_mark_set_val_FIXUP(void *p, struct NewGC *gc) { static int sema_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Sema)); +#else + return 0; +#endif } static int sema_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Sema *s = (Scheme_Sema *)p; gcMARK2(s->first, gc); gcMARK2(s->last, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Sema)); +# endif +#endif } static int sema_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Sema *s = (Scheme_Sema *)p; gcFIXUP2(s->first, gc); gcFIXUP2(s->last, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Sema)); +# endif +#endif } #define sema_val_IS_ATOMIC 0 @@ -2175,11 +3032,15 @@ static int sema_val_FIXUP(void *p, struct NewGC *gc) { static int channel_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Channel)); +#else + return 0; +#endif } static int channel_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Channel *s = (Scheme_Channel *)p; gcMARK2(s->get_first, gc); @@ -2187,11 +3048,17 @@ static int channel_val_MARK(void *p, struct NewGC *gc) { gcMARK2(s->put_first, gc); gcMARK2(s->put_last, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Channel)); +# endif +#endif } static int channel_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Channel *s = (Scheme_Channel *)p; gcFIXUP2(s->get_first, gc); @@ -2199,8 +3066,13 @@ static int channel_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(s->put_first, gc); gcFIXUP2(s->put_last, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Channel)); +# endif +#endif } #define channel_val_IS_ATOMIC 0 @@ -2208,28 +3080,43 @@ static int channel_val_FIXUP(void *p, struct NewGC *gc) { static int channel_put_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Channel_Put)); +#else + return 0; +#endif } static int channel_put_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Channel_Put *s = (Scheme_Channel_Put *)p; gcMARK2(s->ch, gc); gcMARK2(s->val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Channel_Put)); +# endif +#endif } static int channel_put_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Channel_Put *s = (Scheme_Channel_Put *)p; gcFIXUP2(s->ch, gc); gcFIXUP2(s->val, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Channel_Put)); +# endif +#endif } #define channel_put_val_IS_ATOMIC 0 @@ -2237,30 +3124,45 @@ static int channel_put_val_FIXUP(void *p, struct NewGC *gc) { static int hash_table_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Hash_Table)); +#else + return 0; +#endif } static int hash_table_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Hash_Table *ht = (Scheme_Hash_Table *)p; gcMARK2(ht->keys, gc); gcMARK2(ht->vals, gc); gcMARK2(ht->mutex, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Hash_Table)); +# endif +#endif } static int hash_table_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Hash_Table *ht = (Scheme_Hash_Table *)p; gcFIXUP2(ht->keys, gc); gcFIXUP2(ht->vals, gc); gcFIXUP2(ht->mutex, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Hash_Table)); +# endif +#endif } #define hash_table_val_IS_ATOMIC 0 @@ -2268,28 +3170,43 @@ static int hash_table_val_FIXUP(void *p, struct NewGC *gc) { static int bucket_table_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Bucket_Table)); +#else + return 0; +#endif } static int bucket_table_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Bucket_Table *ht = (Scheme_Bucket_Table *)p; gcMARK2(ht->buckets, gc); gcMARK2(ht->mutex, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Bucket_Table)); +# endif +#endif } static int bucket_table_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Bucket_Table *ht = (Scheme_Bucket_Table *)p; gcFIXUP2(ht->buckets, gc); gcFIXUP2(ht->mutex, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Bucket_Table)); +# endif +#endif } #define bucket_table_val_IS_ATOMIC 0 @@ -2297,11 +3214,15 @@ static int bucket_table_val_FIXUP(void *p, struct NewGC *gc) { static int namespace_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Env)); +#else + return 0; +#endif } static int namespace_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Env *e = (Scheme_Env *)p; gcMARK2(e->module, gc); @@ -2344,11 +3265,17 @@ static int namespace_val_MARK(void *p, struct NewGC *gc) { gcMARK2(e->binding_names, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Env)); +# endif +#endif } static int namespace_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Env *e = (Scheme_Env *)p; gcFIXUP2(e->module, gc); @@ -2391,8 +3318,13 @@ static int namespace_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(e->binding_names, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Env)); +# endif +#endif } #define namespace_val_IS_ATOMIC 0 @@ -2400,24 +3332,39 @@ static int namespace_val_FIXUP(void *p, struct NewGC *gc) { static int module_reg_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Module_Registry)); +#else + return 0; +#endif } static int module_reg_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Module_Registry *r = (Scheme_Module_Registry *)p; gcMARK2(r->loaded, gc); gcMARK2(r->exports, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Registry)); +# endif +#endif } static int module_reg_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Module_Registry *r = (Scheme_Module_Registry *)p; gcFIXUP2(r->loaded, gc); gcFIXUP2(r->exports, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Registry)); +# endif +#endif } #define module_reg_val_IS_ATOMIC 0 @@ -2425,18 +3372,33 @@ static int module_reg_val_FIXUP(void *p, struct NewGC *gc) { static int random_state_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Random_State)); +#else + return 0; +#endif } static int random_state_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Random_State)); +# endif +#endif } static int random_state_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Random_State)); +# endif +#endif } #define random_state_val_IS_ATOMIC 1 @@ -2444,28 +3406,43 @@ static int random_state_val_FIXUP(void *p, struct NewGC *gc) { static int compilation_top_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Compilation_Top)); +#else + return 0; +#endif } static int compilation_top_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Compilation_Top *t = (Scheme_Compilation_Top *)p; gcMARK2(t->code, gc); gcMARK2(t->prefix, gc); gcMARK2(t->binding_namess, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Compilation_Top)); +# endif +#endif } static int compilation_top_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Compilation_Top *t = (Scheme_Compilation_Top *)p; gcFIXUP2(t->code, gc); gcFIXUP2(t->prefix, gc); gcFIXUP2(t->binding_namess, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Compilation_Top)); +# endif +#endif } #define compilation_top_val_IS_ATOMIC 0 @@ -2473,36 +3450,51 @@ static int compilation_top_val_FIXUP(void *p, struct NewGC *gc) { static int prefix_val_SIZE(void *p, struct NewGC *gc) { +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS Scheme_Prefix *pf = (Scheme_Prefix *)p; - return gcBYTES_TO_WORDS((sizeof(Scheme_Prefix) + ((pf->num_slots-mzFLEX_DELTA) * sizeof(Scheme_Object *)) + ((((pf->num_slots - pf->num_stxes) + 31) / 32) * sizeof(int)))); +#else + return 0; +#endif } static int prefix_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Prefix *pf = (Scheme_Prefix *)p; int i; for (i = pf->num_slots; i--; ) gcMARK2(pf->a[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Prefix) + ((pf->num_slots-mzFLEX_DELTA) * sizeof(Scheme_Object *)) + ((((pf->num_slots - pf->num_stxes) + 31) / 32) * sizeof(int)))); +# endif +#endif } static int prefix_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Prefix *pf = (Scheme_Prefix *)p; int i; for (i = pf->num_slots; i--; ) gcFIXUP2(pf->a[i], gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS((sizeof(Scheme_Prefix) + ((pf->num_slots-mzFLEX_DELTA) * sizeof(Scheme_Object *)) + ((((pf->num_slots - pf->num_stxes) + 31) / 32) * sizeof(int)))); +# endif +#endif } #define prefix_val_IS_ATOMIC 0 @@ -2510,30 +3502,45 @@ static int prefix_val_FIXUP(void *p, struct NewGC *gc) { static int resolve_prefix_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Resolve_Prefix)); +#else + return 0; +#endif } static int resolve_prefix_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Resolve_Prefix *rp = (Resolve_Prefix *)p; gcMARK2(rp->toplevels, gc); gcMARK2(rp->stxes, gc); gcMARK2(rp->delay_info_rpair, gc); gcMARK2(rp->src_insp_desc, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Resolve_Prefix)); +# endif +#endif } static int resolve_prefix_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Resolve_Prefix *rp = (Resolve_Prefix *)p; gcFIXUP2(rp->toplevels, gc); gcFIXUP2(rp->stxes, gc); gcFIXUP2(rp->delay_info_rpair, gc); gcFIXUP2(rp->src_insp_desc, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Resolve_Prefix)); +# endif +#endif } #define resolve_prefix_val_IS_ATOMIC 0 @@ -2541,30 +3548,45 @@ static int resolve_prefix_val_FIXUP(void *p, struct NewGC *gc) { static int comp_prefix_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Comp_Prefix)); +#else + return 0; +#endif } static int comp_prefix_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Comp_Prefix *cp = (Comp_Prefix *)p; gcMARK2(cp->toplevels, gc); gcMARK2(cp->inline_variants, gc); gcMARK2(cp->unbound, gc); gcMARK2(cp->stxes, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Comp_Prefix)); +# endif +#endif } static int comp_prefix_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Comp_Prefix *cp = (Comp_Prefix *)p; gcFIXUP2(cp->toplevels, gc); gcFIXUP2(cp->inline_variants, gc); gcFIXUP2(cp->unbound, gc); gcFIXUP2(cp->stxes, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Comp_Prefix)); +# endif +#endif } #define comp_prefix_val_IS_ATOMIC 0 @@ -2572,26 +3594,41 @@ static int comp_prefix_val_FIXUP(void *p, struct NewGC *gc) { static int svector_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +#else + return 0; +#endif } static int svector_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcMARK2(SCHEME_SVEC_VEC(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } static int svector_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Object *o = (Scheme_Object *)p; gcFIXUP2(SCHEME_SVEC_VEC(o), gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object)); +# endif +#endif } #define svector_val_IS_ATOMIC 0 @@ -2599,11 +3636,15 @@ static int svector_val_FIXUP(void *p, struct NewGC *gc) { static int stx_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Stx)); +#else + return 0; +#endif } static int stx_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Stx *stx = (Scheme_Stx *)p; gcMARK2(stx->val, gc); gcMARK2(stx->srcloc, gc); @@ -2612,11 +3653,17 @@ static int stx_val_MARK(void *p, struct NewGC *gc) { gcMARK2(stx->shifts, gc); gcMARK2(stx->taints, gc); gcMARK2(stx->props, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Stx)); +# endif +#endif } static int stx_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Stx *stx = (Scheme_Stx *)p; gcFIXUP2(stx->val, gc); gcFIXUP2(stx->srcloc, gc); @@ -2625,8 +3672,13 @@ static int stx_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(stx->shifts, gc); gcFIXUP2(stx->taints, gc); gcFIXUP2(stx->props, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Stx)); +# endif +#endif } #define stx_val_IS_ATOMIC 0 @@ -2634,22 +3686,37 @@ static int stx_val_FIXUP(void *p, struct NewGC *gc) { static int stx_off_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Stx_Offset)); +#else + return 0; +#endif } static int stx_off_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Stx_Offset *o = (Scheme_Stx_Offset *)p; gcMARK2(o->src, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Stx_Offset)); +# endif +#endif } static int stx_off_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Stx_Offset *o = (Scheme_Stx_Offset *)p; gcFIXUP2(o->src, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Stx_Offset)); +# endif +#endif } #define stx_off_val_IS_ATOMIC 0 @@ -2657,11 +3724,15 @@ static int stx_off_val_FIXUP(void *p, struct NewGC *gc) { static int module_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Module)); +#else + return 0; +#endif } static int module_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Module *m = (Scheme_Module *)p; gcMARK2(m->phaseless, gc); @@ -2711,11 +3782,17 @@ static int module_val_MARK(void *p, struct NewGC *gc) { gcMARK2(m->submodule_ancestry, gc); gcMARK2(m->primitive, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module)); +# endif +#endif } static int module_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Module *m = (Scheme_Module *)p; gcFIXUP2(m->phaseless, gc); @@ -2765,8 +3842,13 @@ static int module_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(m->submodule_ancestry, gc); gcFIXUP2(m->primitive, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module)); +# endif +#endif } #define module_val_IS_ATOMIC 0 @@ -2774,11 +3856,15 @@ static int module_val_FIXUP(void *p, struct NewGC *gc) { static int exp_info_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Module_Export_Info)); +#else + return 0; +#endif } static int exp_info_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Module_Export_Info *m = (Scheme_Module_Export_Info *)p; gcMARK2(m->provide_protects, gc); @@ -2787,11 +3873,17 @@ static int exp_info_val_MARK(void *p, struct NewGC *gc) { gcMARK2(m->indirect_syntax_provides, gc); gcMARK2(m->accessible, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Export_Info)); +# endif +#endif } static int exp_info_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Module_Export_Info *m = (Scheme_Module_Export_Info *)p; gcFIXUP2(m->provide_protects, gc); @@ -2800,8 +3892,13 @@ static int exp_info_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(m->indirect_syntax_provides, gc); gcFIXUP2(m->accessible, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Export_Info)); +# endif +#endif } #define exp_info_val_IS_ATOMIC 0 @@ -2809,11 +3906,15 @@ static int exp_info_val_FIXUP(void *p, struct NewGC *gc) { static int module_phase_exports_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Module_Phase_Exports)); +#else + return 0; +#endif } static int module_phase_exports_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Module_Phase_Exports *m = (Scheme_Module_Phase_Exports *)p; gcMARK2(m->phase_index, gc); @@ -2828,11 +3929,17 @@ static int module_phase_exports_val_MARK(void *p, struct NewGC *gc) { gcMARK2(m->ht, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Phase_Exports)); +# endif +#endif } static int module_phase_exports_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Module_Phase_Exports *m = (Scheme_Module_Phase_Exports *)p; gcFIXUP2(m->phase_index, gc); @@ -2847,8 +3954,13 @@ static int module_phase_exports_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(m->ht, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Phase_Exports)); +# endif +#endif } #define module_phase_exports_val_IS_ATOMIC 0 @@ -2856,11 +3968,15 @@ static int module_phase_exports_val_FIXUP(void *p, struct NewGC *gc) { static int module_exports_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Module_Exports)); +#else + return 0; +#endif } static int module_exports_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Module_Exports *m = (Scheme_Module_Exports *)p; gcMARK2(m->rt, gc); @@ -2870,11 +3986,17 @@ static int module_exports_val_MARK(void *p, struct NewGC *gc) { gcMARK2(m->src_modidx, gc); gcMARK2(m->modsrc, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Exports)); +# endif +#endif } static int module_exports_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Module_Exports *m = (Scheme_Module_Exports *)p; gcFIXUP2(m->rt, gc); @@ -2884,8 +4006,13 @@ static int module_exports_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(m->src_modidx, gc); gcFIXUP2(m->modsrc, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Module_Exports)); +# endif +#endif } #define module_exports_val_IS_ATOMIC 0 @@ -2893,11 +4020,15 @@ static int module_exports_val_FIXUP(void *p, struct NewGC *gc) { static int modidx_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Modidx)); +#else + return 0; +#endif } static int modidx_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Modidx *modidx = (Scheme_Modidx *)p; gcMARK2(modidx->path, gc); @@ -2905,11 +4036,17 @@ static int modidx_val_MARK(void *p, struct NewGC *gc) { gcMARK2(modidx->resolved, gc); gcMARK2(modidx->shift_cache, gc); gcMARK2(modidx->cache_next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Modidx)); +# endif +#endif } static int modidx_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Modidx *modidx = (Scheme_Modidx *)p; gcFIXUP2(modidx->path, gc); @@ -2917,8 +4054,13 @@ static int modidx_val_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(modidx->resolved, gc); gcFIXUP2(modidx->shift_cache, gc); gcFIXUP2(modidx->cache_next, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Modidx)); +# endif +#endif } #define modidx_val_IS_ATOMIC 0 @@ -2926,30 +4068,45 @@ static int modidx_val_FIXUP(void *p, struct NewGC *gc) { static int guard_val_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Security_Guard)); +#else + return 0; +#endif } static int guard_val_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Security_Guard *g = (Scheme_Security_Guard *)p; gcMARK2(g->parent, gc); gcMARK2(g->file_proc, gc); gcMARK2(g->network_proc, gc); gcMARK2(g->link_proc, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Security_Guard)); +# endif +#endif } static int guard_val_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Security_Guard *g = (Scheme_Security_Guard *)p; gcFIXUP2(g->parent, gc); gcFIXUP2(g->file_proc, gc); gcFIXUP2(g->network_proc, gc); gcFIXUP2(g->link_proc, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Security_Guard)); +# endif +#endif } #define guard_val_IS_ATOMIC 0 @@ -2957,26 +4114,41 @@ static int guard_val_FIXUP(void *p, struct NewGC *gc) { static int buf_holder_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Jumpup_Buf_Holder)); +#else + return 0; +#endif } static int buf_holder_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Jumpup_Buf_Holder *h = (Scheme_Jumpup_Buf_Holder *)p; MARK_jmpup(&h->buf, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Jumpup_Buf_Holder)); +# endif +#endif } static int buf_holder_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Jumpup_Buf_Holder *h = (Scheme_Jumpup_Buf_Holder *)p; FIXUP_jmpup(&h->buf, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Jumpup_Buf_Holder)); +# endif +#endif } #define buf_holder_IS_ATOMIC 0 @@ -2984,22 +4156,37 @@ static int buf_holder_FIXUP(void *p, struct NewGC *gc) { static int mark_inspector_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Inspector)); +#else + return 0; +#endif } static int mark_inspector_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Inspector *i = (Scheme_Inspector *)p; gcMARK2(i->superior, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Inspector)); +# endif +#endif } static int mark_inspector_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Inspector *i = (Scheme_Inspector *)p; gcFIXUP2(i->superior, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Inspector)); +# endif +#endif } #define mark_inspector_IS_ATOMIC 0 @@ -3007,30 +4194,45 @@ static int mark_inspector_FIXUP(void *p, struct NewGC *gc) { static int mark_pipe_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Pipe)); +#else + return 0; +#endif } static int mark_pipe_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Pipe *pp = (Scheme_Pipe *)p; gcMARK2(pp->buf, gc); gcMARK2(pp->wakeup_on_read, gc); gcMARK2(pp->wakeup_on_write, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Pipe)); +# endif +#endif } static int mark_pipe_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Pipe *pp = (Scheme_Pipe *)p; gcFIXUP2(pp->buf, gc); gcFIXUP2(pp->wakeup_on_read, gc); gcFIXUP2(pp->wakeup_on_write, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Pipe)); +# endif +#endif } #define mark_pipe_IS_ATOMIC 0 @@ -3038,11 +4240,15 @@ static int mark_pipe_FIXUP(void *p, struct NewGC *gc) { static int mark_logger_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Logger)); +#else + return 0; +#endif } static int mark_logger_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Logger *l = (Scheme_Logger *)p; gcMARK2(l->name, gc); gcMARK2(l->parent, gc); @@ -3052,11 +4258,17 @@ static int mark_logger_MARK(void *p, struct NewGC *gc) { gcMARK2(l->stderr_level, gc); gcMARK2(l->propagate_level, gc); gcMARK2(l->readers, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Logger)); +# endif +#endif } static int mark_logger_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Logger *l = (Scheme_Logger *)p; gcFIXUP2(l->name, gc); gcFIXUP2(l->parent, gc); @@ -3066,8 +4278,13 @@ static int mark_logger_FIXUP(void *p, struct NewGC *gc) { gcFIXUP2(l->stderr_level, gc); gcFIXUP2(l->propagate_level, gc); gcFIXUP2(l->readers, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Logger)); +# endif +#endif } #define mark_logger_IS_ATOMIC 0 @@ -3075,28 +4292,43 @@ static int mark_logger_FIXUP(void *p, struct NewGC *gc) { static int mark_log_reader_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Scheme_Log_Reader)); +#else + return 0; +#endif } static int mark_log_reader_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Log_Reader *lr = (Scheme_Log_Reader *)p; gcMARK2(lr->level, gc); gcMARK2(lr->sema, gc); gcMARK2(lr->head, gc); gcMARK2(lr->tail, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Log_Reader)); +# endif +#endif } static int mark_log_reader_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Log_Reader *lr = (Scheme_Log_Reader *)p; gcFIXUP2(lr->level, gc); gcFIXUP2(lr->sema, gc); gcFIXUP2(lr->head, gc); gcFIXUP2(lr->tail, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Scheme_Log_Reader)); +# endif +#endif } #define mark_log_reader_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmark_validate.inc b/racket/src/racket/src/mzmark_validate.inc index 76844350f7..f85aedb5d2 100644 --- a/racket/src/racket/src/mzmark_validate.inc +++ b/racket/src/racket/src/mzmark_validate.inc @@ -1,28 +1,43 @@ /* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */ static int mark_validate_clearing_SIZE(void *p, struct NewGC *gc) { - return +#ifndef GC_NO_SIZE_NEEDED_FROM_PROCS gcBYTES_TO_WORDS(sizeof(Validate_Clearing)); +#else + return 0; +#endif } static int mark_validate_clearing_MARK(void *p, struct NewGC *gc) { +#ifndef GC_NO_MARK_PROCEDURE_NEEDED Validate_Clearing *vc = (Validate_Clearing *)p; gcMARK2(vc->stack, gc); gcMARK2(vc->ncstack, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Validate_Clearing)); +# endif +#endif } static int mark_validate_clearing_FIXUP(void *p, struct NewGC *gc) { +#ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Validate_Clearing *vc = (Validate_Clearing *)p; gcFIXUP2(vc->stack, gc); gcFIXUP2(vc->ncstack, gc); +# ifdef GC_NO_SIZE_NEEDED_FROM_PROCS + return 0; +# else return gcBYTES_TO_WORDS(sizeof(Validate_Clearing)); +# endif +#endif } #define mark_validate_clearing_IS_ATOMIC 0 diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 61a22b3cc0..35316c367b 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -565,11 +565,9 @@ bstring_obj { } symbol_obj { - Scheme_Symbol *s = (Scheme_Symbol *)p; - mark: size: - gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + s->len + 1 - mzFLEX4_DELTA); + gcBYTES_TO_WORDS(sizeof(Scheme_Symbol) + ((Scheme_Symbol *)p)->len + 1 - mzFLEX4_DELTA); } cons_cell { @@ -597,31 +595,25 @@ vector_obj { } fxvector_obj { - Scheme_Vector *vec = (Scheme_Vector *)p; - mark: size: gcBYTES_TO_WORDS((sizeof(Scheme_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); + + ((((Scheme_Vector *)p)->size - mzFLEX_DELTA) * sizeof(Scheme_Object *)))); } flvector_obj { - Scheme_Double_Vector *vec = (Scheme_Double_Vector *)p; - mark: size: gcBYTES_TO_WORDS((sizeof(Scheme_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(double)))); + + ((((Scheme_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(double)))); } #ifdef MZ_LONG_DOUBLE extflvector_obj { - Scheme_Long_Double_Vector *vec = (Scheme_Long_Double_Vector *)p; - mark: size: gcBYTES_TO_WORDS((sizeof(Scheme_Long_Double_Vector) - + ((vec->size - mzFLEX_DELTA) * sizeof(long double)))); + + ((((Scheme_Long_Double_Vector *)p)->size - mzFLEX_DELTA) * sizeof(long double)))); } #endif @@ -771,8 +763,6 @@ thread_val { gcMARK2(pr->self_for_proc_chaperone, gc); - gcMARK2(pr->list_stack, gc); - gcMARK2(pr->kill_data, gc); gcMARK2(pr->private_kill_data, gc); gcMARK2(pr->private_kill_next, gc); @@ -1270,6 +1260,8 @@ mark_comp_env { gcMARK2(e->prefix, gc); gcMARK2(e->next, gc); gcMARK2(e->scopes, gc); + gcMARK2(e->value_name, gc); + gcMARK2(e->observer, gc); gcMARK2(e->binders, gc); gcMARK2(e->bindings, gc); gcMARK2(e->vals, gc); @@ -1429,17 +1421,6 @@ END optimize; START eval; -mark_comp_info { - mark: - Scheme_Compile_Info *i = (Scheme_Compile_Info *)p; - - gcMARK2(i->value_name, gc); - gcMARK2(i->observer, gc); - - size: - gcBYTES_TO_WORDS(sizeof(Scheme_Compile_Info)); -} - mark_saved_stack { mark: Scheme_Saved_Stack *saved = (Scheme_Saved_Stack *)p; diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 156e711f12..d358c322fc 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -183,8 +183,6 @@ typedef struct ReadParams { } ReadParams; #define THREAD_FOR_LOCALS scheme_current_thread -#define local_list_stack (THREAD_FOR_LOCALS->list_stack) -#define local_list_stack_pos (THREAD_FOR_LOCALS->list_stack_pos) static Scheme_Object *read_list(Scheme_Object *port, Scheme_Object *stxsrc, intptr_t line, intptr_t col, intptr_t pos, @@ -560,51 +558,6 @@ void scheme_init_variable_references_constants() } -static Scheme_Simple_Object *malloc_list_stack() -{ -#ifdef MZ_PRECISE_GC - intptr_t sz = sizeof(Scheme_Simple_Object) * NUM_CELLS_PER_STACK; - Scheme_Simple_Object *r; - - if (sz < GC_malloc_stays_put_threshold()) { - sz = GC_malloc_stays_put_threshold(); - while (sz % sizeof(Scheme_Simple_Object)) { - sz++; - } - } - - r = (Scheme_Simple_Object *)GC_malloc_array_tagged(sz); - - /* Must set the tag on the first element: */ - r[0].iso.so.type = scheme_pair_type; - return r; -#else - return MALLOC_N_RT(Scheme_Simple_Object, NUM_CELLS_PER_STACK); -#endif -} - -void scheme_alloc_list_stack(Scheme_Thread *p) -{ - Scheme_Simple_Object *sa; - p->list_stack_pos = 0; - sa = malloc_list_stack(); - p->list_stack = sa; -} - -void scheme_clean_list_stack(Scheme_Thread *p) -{ - if (p->list_stack) { - memset(p->list_stack + p->list_stack_pos, 0, - (NUM_CELLS_PER_STACK - p->list_stack_pos) * sizeof(Scheme_Simple_Object)); -#ifdef MZ_PRECISE_GC - if (!p->list_stack_pos) { - /* Must set the tag on the first element: */ - p->list_stack[0].iso.so.type = scheme_pair_type; - } -#endif - } -} - static void track_indentation(Scheme_Object *indentation, int line, int col) { if (!SCHEME_NULLP(indentation)) { diff --git a/racket/src/racket/src/schemef.h b/racket/src/racket/src/schemef.h index 704f18ba8b..c5e8933b2b 100644 --- a/racket/src/racket/src/schemef.h +++ b/racket/src/racket/src/schemef.h @@ -412,7 +412,6 @@ MZ_EXTERN void *GC_malloc_atomic(size_t size_in_bytes); MZ_EXTERN void *GC_malloc_one_tagged(size_t size_in_bytes); MZ_EXTERN void *GC_malloc_atomic_uncollectable(size_t size_in_bytes); MZ_EXTERN void *scheme_malloc_uncollectable(size_t size_in_bytes); -MZ_EXTERN void *GC_malloc_array_tagged(size_t size_in_bytes); MZ_EXTERN void *GC_malloc_allow_interior(size_t size_in_bytes); MZ_EXTERN void *GC_malloc_atomic_allow_interior(size_t size_in_bytes); MZ_EXTERN void *GC_malloc_tagged_allow_interior(size_t size_in_bytes); diff --git a/racket/src/racket/src/schemex.h b/racket/src/racket/src/schemex.h index 2c2384f1e7..242906670e 100644 --- a/racket/src/racket/src/schemex.h +++ b/racket/src/racket/src/schemex.h @@ -320,7 +320,6 @@ void *(*GC_malloc_atomic)(size_t size_in_bytes); void *(*GC_malloc_one_tagged)(size_t size_in_bytes); void *(*GC_malloc_atomic_uncollectable)(size_t size_in_bytes); void *(*scheme_malloc_uncollectable)(size_t size_in_bytes); -void *(*GC_malloc_array_tagged)(size_t size_in_bytes); void *(*GC_malloc_allow_interior)(size_t size_in_bytes); void *(*GC_malloc_atomic_allow_interior)(size_t size_in_bytes); void *(*GC_malloc_tagged_allow_interior)(size_t size_in_bytes); diff --git a/racket/src/racket/src/schemex.inc b/racket/src/racket/src/schemex.inc index 1eb59eaa8f..741ff989cc 100644 --- a/racket/src/racket/src/schemex.inc +++ b/racket/src/racket/src/schemex.inc @@ -223,7 +223,6 @@ scheme_extension_table->GC_malloc_one_tagged = GC_malloc_one_tagged; scheme_extension_table->GC_malloc_atomic_uncollectable = GC_malloc_atomic_uncollectable; scheme_extension_table->scheme_malloc_uncollectable = scheme_malloc_uncollectable; - scheme_extension_table->GC_malloc_array_tagged = GC_malloc_array_tagged; scheme_extension_table->GC_malloc_allow_interior = GC_malloc_allow_interior; scheme_extension_table->GC_malloc_atomic_allow_interior = GC_malloc_atomic_allow_interior; scheme_extension_table->GC_malloc_tagged_allow_interior = GC_malloc_tagged_allow_interior; diff --git a/racket/src/racket/src/schemexm.h b/racket/src/racket/src/schemexm.h index cfd1bfdcf0..318cad8505 100644 --- a/racket/src/racket/src/schemexm.h +++ b/racket/src/racket/src/schemexm.h @@ -223,7 +223,6 @@ #define GC_malloc_one_tagged (scheme_extension_table->GC_malloc_one_tagged) #define GC_malloc_atomic_uncollectable (scheme_extension_table->GC_malloc_atomic_uncollectable) #define scheme_malloc_uncollectable (scheme_extension_table->scheme_malloc_uncollectable) -#define GC_malloc_array_tagged (scheme_extension_table->GC_malloc_array_tagged) #define GC_malloc_allow_interior (scheme_extension_table->GC_malloc_allow_interior) #define GC_malloc_atomic_allow_interior (scheme_extension_table->GC_malloc_atomic_allow_interior) #define GC_malloc_tagged_allow_interior (scheme_extension_table->GC_malloc_tagged_allow_interior) diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 6bda377bfa..ac938cf7bb 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -112,7 +112,6 @@ extern XFORM_NONGCING int scheme_intern_prim_opt_flags(int); #ifdef MZTAG_REQUIRED # define scheme_malloc_rt(x) scheme_malloc_tagged(x) # define MALLOC_ONE_RT(x) MALLOC_ONE_TAGGED(x) -# define MALLOC_N_RT(x,c) MALLOC_N_TAGGED(x,c) # define MALLOC_ONE_WEAK(x) _MALLOC_N(x, 1, scheme_malloc) # define MALLOC_N_WEAK(x,c) _MALLOC_N(x, c, scheme_malloc) # define MALLOC_ONE_TAGGED_WEAK(x) _MALLOC_N(x, 1, scheme_malloc_tagged) @@ -120,7 +119,6 @@ extern XFORM_NONGCING int scheme_intern_prim_opt_flags(int); #else # define scheme_malloc_rt(x) scheme_malloc(x) # define MALLOC_ONE_RT(x) MALLOC_ONE(x) -# define MALLOC_N_RT(x,c) MALLOC_N(x,c) # define MALLOC_ONE_WEAK(x) MALLOC_ONE_ATOMIC(x) # define MALLOC_N_WEAK(x,c) MALLOC_N_ATOMIC(x,c) # define MALLOC_ONE_WEAK_RT(x) MALLOC_ONE_WEAK(x) @@ -2574,6 +2572,9 @@ typedef struct Scheme_Comp_Env Scheme_Object *scopes; /* can be NULL, a scope, a scope set, or (cons scope-set nobind-scope) */ + Scheme_Object *value_name; /* propagated down */ + Scheme_Object *observer; /* parameter's value (to avoid looking up every time) */ + /* local bindings; */ mzshort num_bindings; /* number of `values' slots */ Scheme_Object **binders; /* identifiers */ @@ -2618,11 +2619,9 @@ typedef struct Scheme_Comp_Env typedef struct Scheme_Compile_Expand_Info { - MZTAG_IF_REQUIRED + /* allocated as atomic */ short comp; short comp_flags; - Scheme_Object *value_name; - Scheme_Object *observer; char dont_mark_local_use; char resolve_module_ids; char pre_unwrapped; @@ -2970,7 +2969,7 @@ void scheme_merge_undefineds(Scheme_Comp_Env *exp_env, Scheme_Comp_Env *env); void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object *a, Scheme_Env *exp_env, Scheme_Object *insp, - Scheme_Compile_Expand_Info *rec, int drec, + Scheme_Compile_Expand_Info *rec, int drec, Scheme_Object *observer, Scheme_Comp_Env *stx_env, Scheme_Comp_Env *rhs_env, int *_pos, Scheme_Object *rename_rib, int replace_value); int scheme_is_sub_env(Scheme_Comp_Env *stx_env, Scheme_Comp_Env *env); @@ -3130,7 +3129,7 @@ void *scheme_module_run_finish(Scheme_Env *menv, Scheme_Env *env); void *scheme_module_exprun_finish(Scheme_Env *menv, int set_ns); void *scheme_module_start_finish(struct Start_Module_Args *a); -Scheme_Object *scheme_build_closure_name(Scheme_Object *code, Scheme_Compile_Info *rec, int drec); +Scheme_Object *scheme_build_closure_name(Scheme_Object *code, Scheme_Comp_Env *env); #define SCHEME_SYNTAX(obj) SCHEME_PTR1_VAL(obj) #define SCHEME_SYNTAX_EXP(obj) SCHEME_PTR2_VAL(obj) diff --git a/racket/src/racket/src/stypes.h b/racket/src/racket/src/stypes.h index 68b9530d19..96784c153c 100644 --- a/racket/src/racket/src/stypes.h +++ b/racket/src/racket/src/stypes.h @@ -233,74 +233,73 @@ enum { scheme_rt_resolve_info, /* 205 */ scheme_rt_unresolve_info, /* 206 */ scheme_rt_optimize_info, /* 207 */ - scheme_rt_compile_info, /* 208 */ - scheme_rt_cont_mark, /* 209 */ - scheme_rt_saved_stack, /* 210 */ - scheme_rt_reply_item, /* 211 */ - scheme_rt_closure_info, /* 212 */ - scheme_rt_overflow, /* 213 */ - scheme_rt_overflow_jmp, /* 214 */ - scheme_rt_meta_cont, /* 215 */ - scheme_rt_dyn_wind_cell, /* 216 */ - scheme_rt_dyn_wind_info, /* 217 */ - scheme_rt_dyn_wind, /* 218 */ - scheme_rt_dup_check, /* 219 */ - scheme_rt_thread_memory, /* 220 */ - scheme_rt_input_file, /* 221 */ - scheme_rt_input_fd, /* 222 */ - scheme_rt_oskit_console_input, /* 223 */ - scheme_rt_tested_input_file, /* 224 */ - scheme_rt_tested_output_file, /* 225 */ - scheme_rt_indexed_string, /* 226 */ - scheme_rt_output_file, /* 227 */ - scheme_rt_load_handler_data, /* 228 */ - scheme_rt_pipe, /* 229 */ - scheme_rt_beos_process, /* 230 */ - scheme_rt_system_child, /* 231 */ - scheme_rt_tcp, /* 232 */ - scheme_rt_write_data, /* 233 */ - scheme_rt_tcp_select_info, /* 234 */ - scheme_rt_param_data, /* 235 */ - scheme_rt_will, /* 236 */ - scheme_rt_linker_name, /* 237 */ - scheme_rt_param_map, /* 238 */ - scheme_rt_finalization, /* 239 */ - scheme_rt_finalizations, /* 240 */ - scheme_rt_cpp_object, /* 241 */ - scheme_rt_cpp_array_object, /* 242 */ - scheme_rt_stack_object, /* 243 */ - scheme_rt_preallocated_object, /* 244 */ - scheme_thread_hop_type, /* 245 */ - scheme_rt_srcloc, /* 246 */ - scheme_rt_evt, /* 247 */ - scheme_rt_syncing, /* 248 */ - scheme_rt_comp_prefix, /* 249 */ - scheme_rt_user_input, /* 250 */ - scheme_rt_user_output, /* 251 */ - scheme_rt_compact_port, /* 252 */ - scheme_rt_read_special_dw, /* 253 */ - scheme_rt_regwork, /* 254 */ - scheme_rt_rx_lazy_string, /* 255 */ - scheme_rt_buf_holder, /* 256 */ - scheme_rt_parameterization, /* 257 */ - scheme_rt_print_params, /* 258 */ - scheme_rt_read_params, /* 259 */ - scheme_rt_native_code, /* 260 */ - scheme_rt_native_code_plus_case, /* 261 */ - scheme_rt_jitter_data, /* 262 */ - scheme_rt_module_exports, /* 263 */ - scheme_rt_delay_load_info, /* 264 */ - scheme_rt_marshal_info, /* 265 */ - scheme_rt_unmarshal_info, /* 266 */ - scheme_rt_runstack, /* 267 */ - scheme_rt_sfs_info, /* 268 */ - scheme_rt_validate_clearing, /* 269 */ - scheme_rt_lightweight_cont, /* 270 */ - scheme_rt_export_info, /* 271 */ - scheme_rt_cont_jmp, /* 272 */ - scheme_rt_letrec_check_frame, /* 273 */ + scheme_rt_cont_mark, /* 208 */ + scheme_rt_saved_stack, /* 209 */ + scheme_rt_reply_item, /* 210 */ + scheme_rt_closure_info, /* 211 */ + scheme_rt_overflow, /* 212 */ + scheme_rt_overflow_jmp, /* 213 */ + scheme_rt_meta_cont, /* 214 */ + scheme_rt_dyn_wind_cell, /* 215 */ + scheme_rt_dyn_wind_info, /* 216 */ + scheme_rt_dyn_wind, /* 217 */ + scheme_rt_dup_check, /* 218 */ + scheme_rt_thread_memory, /* 219 */ + scheme_rt_input_file, /* 220 */ + scheme_rt_input_fd, /* 221 */ + scheme_rt_oskit_console_input, /* 222 */ + scheme_rt_tested_input_file, /* 223 */ + scheme_rt_tested_output_file, /* 224 */ + scheme_rt_indexed_string, /* 225 */ + scheme_rt_output_file, /* 226 */ + scheme_rt_load_handler_data, /* 227 */ + scheme_rt_pipe, /* 228 */ + scheme_rt_beos_process, /* 229 */ + scheme_rt_system_child, /* 230 */ + scheme_rt_tcp, /* 231 */ + scheme_rt_write_data, /* 232 */ + scheme_rt_tcp_select_info, /* 233 */ + scheme_rt_param_data, /* 234 */ + scheme_rt_will, /* 235 */ + scheme_rt_linker_name, /* 236 */ + scheme_rt_param_map, /* 237 */ + scheme_rt_finalization, /* 238 */ + scheme_rt_finalizations, /* 239 */ + scheme_rt_cpp_object, /* 240 */ + scheme_rt_cpp_array_object, /* 241 */ + scheme_rt_stack_object, /* 242 */ + scheme_rt_preallocated_object, /* 243 */ + scheme_thread_hop_type, /* 244 */ + scheme_rt_srcloc, /* 245 */ + scheme_rt_evt, /* 246 */ + scheme_rt_syncing, /* 247 */ + scheme_rt_comp_prefix, /* 248 */ + scheme_rt_user_input, /* 249 */ + scheme_rt_user_output, /* 250 */ + scheme_rt_compact_port, /* 251 */ + scheme_rt_read_special_dw, /* 252 */ + scheme_rt_regwork, /* 253 */ + scheme_rt_rx_lazy_string, /* 254 */ + scheme_rt_buf_holder, /* 255 */ + scheme_rt_parameterization, /* 256 */ + scheme_rt_print_params, /* 257 */ + scheme_rt_read_params, /* 258 */ + scheme_rt_native_code, /* 259 */ + scheme_rt_native_code_plus_case, /* 260 */ + scheme_rt_jitter_data, /* 261 */ + scheme_rt_module_exports, /* 262 */ + scheme_rt_delay_load_info, /* 263 */ + scheme_rt_marshal_info, /* 264 */ + scheme_rt_unmarshal_info, /* 265 */ + scheme_rt_runstack, /* 266 */ + scheme_rt_sfs_info, /* 267 */ + scheme_rt_validate_clearing, /* 268 */ + scheme_rt_lightweight_cont, /* 269 */ + scheme_rt_export_info, /* 270 */ + scheme_rt_cont_jmp, /* 271 */ + scheme_rt_letrec_check_frame, /* 272 */ #endif - scheme_deferred_expr_type, /* 274 */ + scheme_deferred_expr_type, /* 273 */ _scheme_last_type_ }; diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 0ff1b3da06..b31d01f414 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -2413,8 +2413,6 @@ static Scheme_Thread *make_thread(Scheme_Config *config, process->ran_some = 1; - process->list_stack = NULL; - scheme_gmp_tls_init(process->gmp_tls); if (prefix) { @@ -2946,8 +2944,6 @@ static void thread_is_dead(Scheme_Thread *r) r->suspended_box = NULL; r->resumed_box = NULL; - r->list_stack = NULL; - r->t_set_parent = NULL; r->dw = NULL; r->init_config = NULL; @@ -3049,11 +3045,6 @@ static void remove_thread(Scheme_Thread *r) r->ku.multiple.array = NULL; r->values_buffer = NULL; -#ifndef SENORA_GC_NO_FREE - if (r->list_stack) - GC_free(r->list_stack); -#endif - thread_is_dead(r); /* In case we kill a thread while in a bignum operation: */ @@ -3530,9 +3521,6 @@ Scheme_Object *scheme_call_as_nested_thread(int argc, Scheme_Object *argv[], voi } np->tail_buffer_size = p->tail_buffer_size; - np->list_stack = p->list_stack; - np->list_stack_pos = p->list_stack_pos; - scheme_gmp_tls_init(np->gmp_tls); /* np->prev = NULL; - 0ed by allocation */ @@ -9018,9 +9006,6 @@ static void prepare_thread_for_GC(Scheme_Object *t) } p->spare_runstack = NULL; - - /* zero ununsed part of list stack */ - scheme_clean_list_stack(p); } void scheme_prepare_this_thread_for_GC(Scheme_Thread *p) From 3d69846046d6d57cf6189bd89cd9bfd20c185981 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 14 Sep 2015 15:08:37 -0600 Subject: [PATCH 228/381] GC: fuse mark and fixup passes, usually In the common case of a minor GC without a generation 1/2 or a major GC without compaction, a single pass suffices to both mark and update references. This change reduces overall GC time by 10%-25% on typical programs. --- .../scribblings/inside/memory.scrbl | 46 ++-- racket/src/racket/gc2/README | 34 ++- racket/src/racket/gc2/gc2.h | 16 +- racket/src/racket/gc2/newgc.c | 199 ++++++++++-------- racket/src/racket/gc2/newgc.h | 1 + racket/src/racket/gc2/weak.c | 6 +- racket/src/racket/src/eval.c | 22 ++ racket/src/racket/src/mzclpf_post.inc | 5 + racket/src/racket/src/mzmark_type.inc | 33 +-- racket/src/racket/src/mzmarksrc.c | 8 +- racket/src/racket/src/schemef.h | 2 +- racket/src/racket/src/schemex.h | 2 +- racket/src/racket/src/schpriv.h | 5 +- 13 files changed, 231 insertions(+), 148 deletions(-) diff --git a/pkgs/racket-doc/scribblings/inside/memory.scrbl b/pkgs/racket-doc/scribblings/inside/memory.scrbl index 84ccb28783..b010d2d1f8 100644 --- a/pkgs/racket-doc/scribblings/inside/memory.scrbl +++ b/pkgs/racket-doc/scribblings/inside/memory.scrbl @@ -196,28 +196,28 @@ A size procedure simply takes a pointer to an object with the tag and returns its size in words (not bytes). The @cppi{gcBYTES_TO_WORDS} macro converts a byte count to a word count. -A mark procedure is used to trace references among objects without -moving any objects. The procedure takes a pointer to an object, and it -should apply the @cppi{gcMARK} macro to every pointer within the -object. The mark procedure should return the same result as the size -procedure. +A mark procedure is used to trace references among objects. The +procedure takes a pointer to an object, and it should apply the +@cppi{gcMARK} macro to every pointer within the object. The mark +procedure should return the same result as the size procedure. -A fixup procedure is used to update references to objects after or -while they are moved. The procedure takes a pointer to an object, and -it should apply the @cppi{gcFIXUP} macro to every pointer within the -object; the expansion of this macro takes the address of its -argument. The fixup procedure should return the same result as the -size procedure. +A fixup procedure is potentially used to update references to objects +that have moved, although the mark procedure may have moved objects +and updated references already. The fixup procedure takes a pointer to +an object, and it should apply the @cppi{gcFIXUP} macro to every +pointer within the object. The fixup procedure should return the same +result as the size procedure. -Depending on the collector's implementation, the mark or fixup -procedure might not be used. For example, the collector may only use -the mark procedure and not actually move the object. Or it may use the -fixup procedure to mark and move objects at the same time. To -dereference an object pointer during a fixup procedure, use +Depending on the collector's implementation, the @cpp{gcMARK} and/or +@cpp{gcFIXUP} macros may take take the address of their arguments, and +the fixup procedure might not be used. For example, the collector may +only use the mark procedure and not actually move the object. Or it +may use mark to move objects at the same time. To dereference an +object pointer during a mark or fixup procedure, use @cppi{GC_resolve} +to convert a potentially old address to the location where the object +has been moved. To dereference an object pointer during a fixup procedure, use @cppi{GC_fixup_self} to convert the address passed to the procedure to -refer to the potentially moved object, and use @cppi{GC_resolve} to -convert an address that is not yet fixed up to determine the object's -current location. +refer to the potentially moved object. When allocating a tagged object in 3m, the tag must be installed immediately after the object is allocated---or, at least, before the @@ -1106,9 +1106,7 @@ If the result of the size procedure is a constant, then pass a 3m only. Can be called by a size, mark, or fixup procedure that is registered with @cpp{GC_register_traversers}. It returns the current address of -an object @var{p} that might have been moved already, where @var{p} -corresponds to an object that is referenced directly by the object -being sized, marked, or fixed. This translation is necessary, for +an object @var{p} that might have been moved already. This translation is necessary, for example, if the size or structure of an object depends on the content of an object it references. For example, the size of a class instance usually depends on a field count that is stored in the class. A fixup @@ -1120,7 +1118,9 @@ fixing it.} 3m only. Can be called by a fixup procedure that is registered with @cpp{GC_register_traversers}. It returns the final address of @var{p}, -which must be the pointer passed to the fixup procedure. For some +which must be the pointer passed to the fixup procedure. The +@cpp{GC_resolve} function would produce the same result, but +@cpp{GC_fixup_self} may be more efficient. For some implementations of the memory manager, the result is the same as @var{p}, either because objects are not moved or because the object is moved before it is fixed. With other implementations, an object might diff --git a/racket/src/racket/gc2/README b/racket/src/racket/gc2/README index 8db9a74ea2..18b070bbd2 100644 --- a/racket/src/racket/gc2/README +++ b/racket/src/racket/gc2/README @@ -59,6 +59,27 @@ GC_get_thread_stack_base() (which is supplied by Racket). More generally, GC_mark_variable_stack() can be used to GC a stack that has been copied into the heap. See below for more details. +Marking and Moving Objects +-------------------------- + +Cooperation between the garbage collector's movement of objects and +Racket's view of object shapes (pointers versus non-pointers) is +mediated by "mark" and "fixup" functions: + + * The "mark" pass traverses objects in the heap, potentially moving + them and adjusting references. + + * An optional extra "fixup" pass further adjusts references to moved + objects. + +The mark and fixup steps are exposed by gcMARK and gcFIXUP macros that +are provided by the collector. In addition, the collector provides a +GC_resolve operation, which converts an object's old address to a new +one in the case that the object is being moved; given an object's new +address GC_resolve returns the same address. A GC_is_marked operation +reports whether an object at its old address has been marked; it works +only on old addresses. + Memory Kinds ------------ @@ -72,19 +93,14 @@ Racket allocates the following kinds of memory objects: o an operation for obtaining the value's size in words (not bytes!); - o an operation for marking pointers within the object; and + o an operation for marking pointers within the object; and - o an operation for "fixing up" pointers in the object to other - objects that have been moved. + o an operation for another fixup pass. The mark and fixup procedures use the gcMARK and gcFIXUP macros provided by the collector. The mark and fixup operations also - return the size of the object, like the size procedure. - - Note that a two-space copying collector might use only the fixup - operation, while a non-moving collector might use only the mark - operation. However, Racket currently relies on at least fixup - calls for scheme_runstack_rt-tagged objects. + return the size of the object, like the size procedure, unless + GC_NO_SIZE_NEEDED_FROM_PROCS is defined. * Atomic - The allocated object contains no pointers to other allocated objects. diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index 9af444821a..9519db0e1b 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -358,9 +358,9 @@ GC2_EXTERN void *GC_fixup_self(void *p); be moved after fixup. */ /* INTERNAL for the current implemenation (used by macros): */ -GC2_EXTERN void GC_mark(const void *p); +GC2_EXTERN void GC_mark(void *p); GC2_EXTERN void GC_fixup(void *p); -GC2_EXTERN void GC_mark2(const void *p, struct NewGC *gc); +GC2_EXTERN void GC_mark2(void *p, struct NewGC *gc); GC2_EXTERN void GC_fixup2(void *p, struct NewGC *gc); /* Used in the expansion of gcMARK and gcFIXUP. @@ -584,12 +584,12 @@ GC2_EXTERN void GC_set_backpointer_object(void *p); #else # define gcLOG_WORD_SIZE 2 #endif -#define gcMARK(x) GC_mark(x) -#define gcMARK2(x, gc) GC_mark2(x, gc) -#define gcMARK_TYPED(t, x) gcMARK(x) -#define gcMARK2_TYPED(t, x, gc) gcMARK2(x, gc) -#define gcMARK_TYPED_NOW(t, x) gcMARK(x) -#define gcMARK2_TYPED_NOW(t, x, gc) gcMARK(x, gc) +#define gcMARK(x) GC_mark(&(x)) +#define gcMARK2(x, gc) GC_mark2(&(x), gc) +#define gcMARK_TYPED(t, x) gcMARK(&(x)) +#define gcMARK2_TYPED(t, x, gc) gcMARK2(&(x), gc) +#define gcMARK_TYPED_NOW(t, x) gcMARK(&(x)) +#define gcMARK2_TYPED_NOW(t, x, gc) gcMARK(&(x), gc) #define gcFIXUP_TYPED_NOW(t, x) GC_fixup(&(x)) #define gcFIXUP2_TYPED_NOW(t, x, gc) GC_fixup2(&(x), gc) #define gcFIXUP_TYPED(t, x) gcFIXUP_TYPED_NOW(void*, x) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index eef4a2b84a..ea2328c3aa 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2355,7 +2355,7 @@ void GC_fixup_variable_stack(void **var_stack, #include "roots.c" -#define traverse_roots(gcMUCK, set_bt_src) { \ +#define traverse_roots(gcMUCK2, gc, set_bt_src) { \ uintptr_t j; \ Roots *roots = &gc->roots; \ if(roots->roots) { \ @@ -2365,7 +2365,7 @@ void GC_fixup_variable_stack(void **var_stack, void **end = (void**)roots->roots[j+1]; \ while(start < end) { \ set_bt_src(gc, start, BT_ROOT); \ - gcMUCK(*start++); \ + gcMUCK2(*start++, gc); \ } \ } \ } \ @@ -2373,12 +2373,12 @@ void GC_fixup_variable_stack(void **var_stack, inline static void mark_roots(NewGC *gc) { - traverse_roots(gcMARK, set_backtrace_source); + traverse_roots(gcMARK2, gc, set_backtrace_source); } inline static void repair_roots(NewGC *gc) { - traverse_roots(gcFIXUP, three_arg_no_op); + traverse_roots(gcFIXUP2, gc, three_arg_no_op); } #include "immobile_boxes.c" @@ -2398,20 +2398,23 @@ inline static void mark_finalizer_structs(NewGC *gc) { Fnl *fnl; + set_backtrace_source(gc, &gc->finalizers, BT_ROOT); + gcMARK2(gc->finalizers, gc); for(fnl = gc->finalizers; fnl; fnl = fnl->next) { - set_backtrace_source(gc, &gc->finalizers, BT_ROOT); - gcMARK2(fnl, gc); - fnl = GC_resolve2(fnl, gc); set_backtrace_source(gc, fnl, BT_FINALIZER); gcMARK2(fnl->data, gc); + set_backtrace_source(gc, &gc->finalizers, BT_ROOT); + gcMARK2(fnl->next, gc); } - for(fnl = GC_resolve2(gc->run_queue, gc); fnl; fnl = fnl->next) { - set_backtrace_source(gc, &gc->run_queue, BT_ROOT); - gcMARK2(fnl, gc); - fnl = GC_resolve2(fnl, gc); + + set_backtrace_source(gc, &gc->run_queue, BT_ROOT); + gcMARK2(gc->run_queue, gc); + for(fnl = gc->run_queue; fnl; fnl = fnl->next) { set_backtrace_source(gc, fnl, BT_FINALIZER); gcMARK2(fnl->data, gc); gcMARK2(fnl->p, gc); + set_backtrace_source(gc, &gc->finalizers, BT_ROOT); + gcMARK2(fnl->next, gc); } } @@ -2468,10 +2471,14 @@ inline static void check_finalizers(NewGC *gc, int level) --gc->num_fnls; work = next; - } else { + } else { + void *p; GCDEBUG((DEBUGOUTF, "CFNL: Not finalizing %p (level %i on %p): %p / %i\n", work, work->eager_level, work->p, pagemap_find_page(gc->page_maps, work->p), marked(work->p))); + p = GC_resolve2(work->p, gc); + if (p != work->p) + work->p = p; prev = work; work = GC_resolve2(work->next, gc); } @@ -3426,8 +3433,8 @@ static void mark_recur_or_push_ptr(struct NewGC *gc, void *p, int is_a_master_pa { Scheme_Object *pr = (Scheme_Object *)p; gc->mark_depth++; - GC_mark2(SCHEME_CDR(pr), gc); - GC_mark2(SCHEME_CAR(pr), gc); + gcMARK2(SCHEME_CDR(pr), gc); + gcMARK2(SCHEME_CAR(pr), gc); --gc->mark_depth; } return; @@ -3440,11 +3447,11 @@ static void mark_recur_or_push_ptr(struct NewGC *gc, void *p, int is_a_master_pa } /* This is the first mark routine. It's a bit complicated. */ -void GC_mark2(const void *const_p, struct NewGC *gc) +void GC_mark2(void *pp, struct NewGC *gc) { int is_a_master_page = 0; mpage *page; - void *p = (void*)const_p; + void *p = *(void **)pp; if(!p || (NUM(p) & 0x1)) { GCDEBUG((DEBUGOUTF, "Not marking %p (bad ptr)\n", p)); @@ -3538,6 +3545,8 @@ void GC_mark2(const void *const_p, struct NewGC *gc) if(ohead->mark) { GCDEBUG((DEBUGOUTF,"Not marking %p (already marked)\n", p)); RELEASE_PAGE_LOCK(is_a_master_page, page); + if (ohead->moved) + *(void **)pp = *(void **)p; return; } @@ -3592,6 +3601,9 @@ void GC_mark2(const void *const_p, struct NewGC *gc) gen_half_allocate_and_setup_new_page(gc); work = gc->gen_half.curr_alloc_page; backtrace_new_gen_half_page(gc, work); + /* since we're using a gen-1/2 half, we'll need a fixup pass + to record backpointers */ + gc->need_fixup = 1; } newplace = PTR(NUM(work->addr) + work->size); work->size += size; @@ -3677,6 +3689,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) /* set forwarding pointer */ GCDEBUG((DEBUGOUTF,"Marking %p (moved to %p on page %p)\n", p, newp, work)); *(void**)p = newp; + *(void **)pp = newp; mark_recur_or_push_ptr(gc, newp, is_a_master_page); } } @@ -3685,9 +3698,9 @@ void GC_mark2(const void *const_p, struct NewGC *gc) RELEASE_PAGE_LOCK(is_a_master_page, page); } -void GC_mark(const void *const_p) +void GC_mark(void *pp) { - GC_mark2(const_p, GC_get_GC()); + GC_mark2(pp, GC_get_GC()); } /* this is the second mark routine. It's not quite as complicated. */ @@ -3745,8 +3758,8 @@ static inline void propagate_marks_worker(NewGC *gc, void *pp) case PAGE_PAIR: { Scheme_Object *p = (Scheme_Object *)start; - GC_mark2(SCHEME_CDR(p), gc); - GC_mark2(SCHEME_CAR(p), gc); + gcMARK2(SCHEME_CDR(p), gc); + gcMARK2(SCHEME_CAR(p), gc); } break; } @@ -3830,13 +3843,11 @@ void GC_fixup2(void *pp, struct NewGC *gc) /* !gc->gc_full => info->moved */ if (info->moved) { *(void**)pp = *(void**)p; - if (info->type) - gc->back_pointers = 1; } else { GCDEBUG((DEBUGOUTF, "Not repairing %p from %p (not moved)\n",p,pp)); - if (page->generation < AGE_GEN_1) - gc->back_pointers = 1; } + if (page->generation < AGE_GEN_1) + gc->back_pointers = 1; } else { #ifdef POINTER_OWNERSHIP_CHECK check_page_owner(gc, p); @@ -4342,6 +4353,8 @@ inline static void do_heap_compact(NewGC *gc) GCDEBUG((DEBUGOUTF, "Compacting page %p: new version at %p\n", work, npage)); + gc->need_fixup = 1; + if (npage == work) { /* Need to insert a page: */ npage = allocate_compact_target(gc, work); @@ -4412,7 +4425,7 @@ inline static void do_heap_compact(NewGC *gc) } } -static int repair_mixed_page(NewGC *gc, mpage *page, void **end) +static int repair_mixed_page(NewGC *gc, mpage *page, void **end, int need_fixup) { void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); Fixup2_Proc *fixup_table = gc->fixup_table; @@ -4421,38 +4434,38 @@ static int repair_mixed_page(NewGC *gc, mpage *page, void **end) while (start <= end) { objhead *info = (objhead *)start; if (info->mark) { - switch(info->type) { - case PAGE_ARRAY: - { - void **tempend = PPTR(info) + info->size; - start = OBJHEAD_TO_OBJPTR(start); - while (start < tempend) gcFIXUP2(*start++, gc); + if (need_fixup) { + switch(info->type) { + case PAGE_ARRAY: + { + void **tempend = PPTR(info) + info->size, **tmpstart; + tmpstart = OBJHEAD_TO_OBJPTR(start); + while (tmpstart < tempend) gcFIXUP2(*tmpstart++, gc); + } + break; + case PAGE_TAGGED: + { + void *obj_start = OBJHEAD_TO_OBJPTR(start); + unsigned short tag = *(unsigned short *)obj_start; + ASSERT_TAG(tag); + fixup_table[tag](obj_start, gc); + } + break; + case PAGE_ATOMIC: + break; + case PAGE_PAIR: + { + Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + } + break; + default: + printf("Unhandled info->type %i\n", info->type); + abort(); } - break; - case PAGE_TAGGED: - { - void *obj_start = OBJHEAD_TO_OBJPTR(start); - unsigned short tag = *(unsigned short *)obj_start; - ASSERT_TAG(tag); - fixup_table[tag](obj_start, gc); - start += info->size; - } - break; - case PAGE_ATOMIC: - start += info->size; - break; - case PAGE_PAIR: - { - Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); - start += info->size; - } - break; - default: - printf("Unhandled info->type %i\n", info->type); - abort(); } + start += info->size; info->mark = 0; non_dead++; } else { @@ -4498,7 +4511,6 @@ static void chain_marked_on(NewGC *gc) } #if 0 -# define CHECK_MARKED_ON_IN_MODIFIED_CHAIN static void chain_marked_on_check(NewGC *gc) { mpage *page, *xpage; @@ -4547,6 +4559,7 @@ static void repair_heap(NewGC *gc) uintptr_t memory_in_use; mpage *page, *next; Fixup2_Proc *fixup_table = gc->fixup_table; + int need_fixup; /* These pages are guaranteed not to be protected, because they've been marked on or marked from. @@ -4558,6 +4571,8 @@ static void repair_heap(NewGC *gc) gc->modified_next = NULL; memory_in_use = gc->memory_in_use; + + need_fixup = gc->need_fixup; for (; page; page = next) { GC_ASSERT(page->marked_on || page->marked_from); @@ -4579,28 +4594,30 @@ static void repair_heap(NewGC *gc) GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", page, start)); page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark */ - switch(page->page_type) { - case PAGE_TAGGED: - fixup_table[*(unsigned short*)start](start, gc); - break; - case PAGE_ATOMIC: break; - case PAGE_ARRAY: - while(start < end) gcFIXUP2(*(start++), gc); - break; - case PAGE_PAIR: - { - Scheme_Object *p = (Scheme_Object *)start; - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); + if (need_fixup) { + switch(page->page_type) { + case PAGE_TAGGED: + fixup_table[*(unsigned short*)start](start, gc); + break; + case PAGE_ATOMIC: break; + case PAGE_ARRAY: + while(start < end) gcFIXUP2(*(start++), gc); + break; + case PAGE_PAIR: + { + Scheme_Object *p = (Scheme_Object *)start; + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + } + break; } - break; } memory_in_use += page->size; } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { void **start = PPTR(NUM(page->addr) + page->previous_size); void **end = PAGE_END_VSS(page); - + GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", page, start)); switch(page->page_type) { @@ -4613,7 +4630,8 @@ static void repair_heap(NewGC *gc) unsigned short tag = *(unsigned short *)obj_start; ASSERT_TAG(tag); info->mark = 0; - fixup_table[tag](obj_start, gc); + if (need_fixup) + fixup_table[tag](obj_start, gc); } else info->dead = 1; start += info->size; @@ -4635,8 +4653,11 @@ static void repair_heap(NewGC *gc) size_t size = info->size; if(info->mark) { void **tempend = PPTR(info) + info->size; - start = OBJHEAD_TO_OBJPTR(start); - while(start < tempend) gcFIXUP2(*start++, gc); + if (need_fixup) { + start = OBJHEAD_TO_OBJPTR(start); + while(start < tempend) gcFIXUP2(*start++, gc); + } else + start = tempend; info->mark = 0; } else { info->dead = 1; @@ -4648,9 +4669,11 @@ static void repair_heap(NewGC *gc) while(start < end) { objhead *info = (objhead *)start; if(info->mark) { - Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); + if (need_fixup) { + Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + } info->mark = 0; } else info->dead = 1; @@ -4664,7 +4687,7 @@ static void repair_heap(NewGC *gc) } else { int non_dead; GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); - non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size)); + non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size), need_fixup); page->live_size = (page->size * non_dead); memory_in_use += page->live_size; page->previous_size = PREFIX_SIZE; /* start next block search at the beginning */ @@ -4687,7 +4710,7 @@ static void repair_heap(NewGC *gc) /* All gen-half pages count as modified: */ for (page = gc->gen_half.pages; page; page = page->next) { GC_ASSERT(page->generation == AGE_GEN_HALF); - (void)repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1)); + (void)repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1), need_fixup); } memory_in_use += gen_half_size_in_use(gc); @@ -5049,6 +5072,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin } gc->gen0_phantom_count = 0; + gc->need_fixup = 0; + TIME_INIT(); /* inform the system (if it wants us to) that we're starting collection */ @@ -5136,7 +5161,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin #if MZ_GC_BACKTRACE if (0) #endif - if(gc->gc_full) + if (gc->gc_full) if (premaster_or_place_gc(gc) || switching_master) do_heap_compact(gc); TIME_STEP("compacted"); @@ -5148,12 +5173,14 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin BTC_clean_up(gc); #endif TIME_STEP("cleaned"); - repair_finalizer_structs(gc); - repair_roots(gc); - repair_immobiles(gc); - if (premaster_or_place_gc(gc)) - GC_fixup_variable_stack(GC_variable_stack, 0, get_stack_base(gc), NULL); - TIME_STEP("reparied roots"); + if (gc->need_fixup) { + repair_finalizer_structs(gc); + repair_roots(gc); + repair_immobiles(gc); + if (premaster_or_place_gc(gc)) + GC_fixup_variable_stack(GC_variable_stack, 0, get_stack_base(gc), NULL); + TIME_STEP("reparied roots"); + } if (gc->gc_full && postmaster_and_master_gc(gc)) chain_marked_on(gc); else if (gc->gc_full) diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 097671f1c4..4efa7de96b 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -178,6 +178,7 @@ typedef struct NewGC { unsigned char gc_full :1; /* a flag saying if this is a full/major collection */ unsigned char running_finalizers :1; unsigned char back_pointers :1; + unsigned char need_fixup :1; /* blame the child */ unsigned int doing_memory_accounting :1; diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index 91317889e4..502f878b8e 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -123,6 +123,8 @@ static void zero_weak_arrays(GCTYPE *gc, int force_zero) void *p = data[i]; if (p && (force_zero || !is_marked(gc, p))) data[i] = wa->replace_val; + else + data[i] = GC_resolve2(p, gc); } wa = wa->next; @@ -223,7 +225,8 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) *(p + wb->soffset) = NULL; wb->secondary_erase = NULL; } - } + } else + wb->val = GC_resolve2(wb->val, gc); wb = wb->next; } @@ -318,6 +321,7 @@ static int mark_ready_ephemerons(GCTYPE *gc) for (eph = gc->ephemerons; eph; eph = next) { next = eph->next; if (is_marked(gc, eph->key)) { + eph->key = GC_resolve2(eph->key, gc); gcMARK2(eph->val, gc); gc->num_last_seen_ephemerons++; did_one = 1; diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 72f5080e52..214e4cfdf6 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -6059,6 +6059,7 @@ static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC { if (scheme_prefix_finalize != (Scheme_Prefix *)0x1) { Scheme_Prefix *pf = scheme_prefix_finalize, *next; + Scheme_Object *clo; int i, *use_bits, maxpos; scheme_prefix_finalize = (Scheme_Prefix *)0x1; @@ -6111,6 +6112,27 @@ static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC for (i = (maxpos + 31) / 32; i--; ) use_bits[i] = 0; + /* Fix up closures that reference this prefix: */ + clo = (Scheme_Object *)GC_resolve2(pf->fixup_chain, gc); + pf->fixup_chain = NULL; + while (clo) { + Scheme_Object *next; + if (SCHEME_TYPE(clo) == scheme_closure_type) { + Scheme_Closure *cl = (Scheme_Closure *)clo; + int closure_size = ((Scheme_Closure_Data *)GC_resolve2(cl->code, gc))->closure_size; + next = cl->vals[closure_size - 1]; + cl->vals[closure_size-1] = (Scheme_Object *)pf; + } else if (SCHEME_TYPE(clo) == scheme_native_closure_type) { + Scheme_Native_Closure *cl = (Scheme_Native_Closure *)clo; + int closure_size = ((Scheme_Native_Closure_Data *)GC_resolve2(cl->code, gc))->closure_size; + next = cl->vals[closure_size - 1]; + cl->vals[closure_size-1] = (Scheme_Object *)pf; + } else { + abort(); + } + clo = (Scheme_Object *)GC_resolve2(next, gc); + } + /* Next */ next = pf->next_final; pf->next_final = NULL; diff --git a/racket/src/racket/src/mzclpf_post.inc b/racket/src/racket/src/mzclpf_post.inc index 1de1e0009b..7fb3e2b4c5 100644 --- a/racket/src/racket/src/mzclpf_post.inc +++ b/racket/src/racket/src/mzclpf_post.inc @@ -29,6 +29,11 @@ } mark_stxes = 0; + /* Add this closure to the chain to be repaired when the + prefix is marked (and potentially moved): */ + c->vals[closure_size - 1] = pf->fixup_chain; + pf->fixup_chain = (Scheme_Object *)c; + /* Mark just the elements of the prefix that are (newly) used: */ if ((uintptr_t)data->tl_map & 0x1) { map = ((uintptr_t)data->tl_map) >> 1; diff --git a/racket/src/racket/src/mzmark_type.inc b/racket/src/racket/src/mzmark_type.inc index c8301ef6cf..dab3b02a16 100644 --- a/racket/src/racket/src/mzmark_type.inc +++ b/racket/src/racket/src/mzmark_type.inc @@ -1775,7 +1775,7 @@ static int bignum_obj_MARK(void *p, struct NewGC *gc) { if (!SCHEME_BIGINLINE(b)) { gcMARK2(b->digits, gc); } else { - + b->digits = ((Small_Bignum *)GC_fixup_self(b))->v; } # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS @@ -2852,6 +2852,22 @@ static int runstack_val_MARK(void *p, struct NewGC *gc) { gcMARK2(*a, gc); a++; } + + /* Zero out the part that we didn't mark, in case it becomes + live later. */ + a = (void **)s + 5; + b = (void **)s + 5 + s[2]; + while (a < b) { + *a = RUNSTACK_ZERO_VAL; + a++; + } + a = (void **)s + 5 + s[3]; + b = (void **)s + 5 + (s[1] - 5); + while (a < b) { + *a = RUNSTACK_ZERO_VAL; + a++; + } + # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS return 0; # else @@ -2872,20 +2888,7 @@ static int runstack_val_FIXUP(void *p, struct NewGC *gc) { a++; } - /* Zero out the part that we didn't mark, in case it becomes - live later. */ - a = (void **)s + 5; - b = (void **)s + 5 + s[2]; - while (a < b) { - *a = RUNSTACK_ZERO_VAL; - a++; - } - a = (void **)s + 5 + s[3]; - b = (void **)s + 5 + (s[1] - 5); - while (a < b) { - *a = RUNSTACK_ZERO_VAL; - a++; - } + # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS return 0; # else diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 35316c367b..31e8fd52f1 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -483,7 +483,7 @@ bignum_obj { if (!SCHEME_BIGINLINE(b)) { gcMARK2(b->digits, gc); } else { - FIXUP_ONLY(b->digits = ((Small_Bignum *)GC_fixup_self(b))->v;) + b->digits = ((Small_Bignum *)GC_fixup_self(b))->v; } size: @@ -811,8 +811,8 @@ runstack_val { gcMARK2(*a, gc); a++; } - more: - fixup: + + START_MARK_ONLY; /* Zero out the part that we didn't mark, in case it becomes live later. */ a = (void **)s + 5; @@ -827,6 +827,8 @@ runstack_val { *a = RUNSTACK_ZERO_VAL; a++; } + END_MARK_ONLY; + size: s[1]; } diff --git a/racket/src/racket/src/schemef.h b/racket/src/racket/src/schemef.h index c5e8933b2b..b59b1317e8 100644 --- a/racket/src/racket/src/schemef.h +++ b/racket/src/racket/src/schemef.h @@ -472,7 +472,7 @@ MZ_EXTERN void **GC_variable_stack; MZ_EXTERN void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark, Fixup_Proc fixup, int is_constant_size, int is_atomic); MZ_EXTERN void *GC_resolve(void *p); -MZ_EXTERN void GC_mark(const void *p); +MZ_EXTERN void GC_mark(void *p); MZ_EXTERN void GC_fixup(void *p); MZ_EXTERN void *GC_fixup_self(void *p); #endif diff --git a/racket/src/racket/src/schemex.h b/racket/src/racket/src/schemex.h index 242906670e..f120dbd7ea 100644 --- a/racket/src/racket/src/schemex.h +++ b/racket/src/racket/src/schemex.h @@ -370,7 +370,7 @@ void **GC_variable_stack; void (*GC_register_traversers)(short tag, Size_Proc size, Mark_Proc mark, Fixup_Proc fixup, int is_constant_size, int is_atomic); void *(*GC_resolve)(void *p); -void (*GC_mark)(const void *p); +void (*GC_mark)(void *p); void (*GC_fixup)(void *p); void *(*GC_fixup_self)(void *p); #endif diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index ac938cf7bb..73f6f05afd 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2455,7 +2455,10 @@ typedef struct Scheme_Prefix { Scheme_Object so; /* scheme_prefix_type */ int num_slots, num_toplevels, num_stxes; +#ifdef MZ_PRECISE_GC struct Scheme_Prefix *next_final; /* for special GC handling */ + struct Scheme_Object *fixup_chain; /* for special GC handling */ +#endif #ifdef MZ_GC_BACKTRACE Scheme_Object *backpointer; #endif @@ -2709,7 +2712,7 @@ XFORM_NONGCING int scheme_boxmap_get(mzshort *boxmap, int j, int delta); int scheme_has_method_property(Scheme_Object *code); -typedef struct { +typedef struct Scheme_Closure { Scheme_Object so; Scheme_Closure_Data *code; Scheme_Object *vals[mzFLEX_ARRAY_DECL]; From 0781d0fa4660d755be8393ac1d13145651c2ff9b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 14 Sep 2015 19:10:18 -0600 Subject: [PATCH 229/381] GC: refine decision for old-generation compaction Compact fewer blocks by moving them only when other blocks have room. Also, fix block protection tracking in the case of a page count that isn't divisible by 8. --- racket/src/racket/gc2/block_cache.c | 68 ++++++++++++++++++++--------- racket/src/racket/gc2/newgc.c | 21 +++++---- 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/racket/src/racket/gc2/block_cache.c b/racket/src/racket/gc2/block_cache.c index 145d059ab3..eba6fe6f69 100644 --- a/racket/src/racket/gc2/block_cache.c +++ b/racket/src/racket/gc2/block_cache.c @@ -41,7 +41,7 @@ typedef struct block_desc { intptr_t totalcnt; intptr_t freecnt; struct block_group *group; - int in_queue; + char in_queue, want_compact; } block_desc; #define BD_BLOCK_PTR_TO_POS(p, bd) (((char *)(p) - (char *)((bd)->block)) >> LOG_APAGE_SIZE) @@ -92,7 +92,7 @@ static ssize_t block_cache_free(BlockCache* bc) { return acf; } -static block_desc *bc_alloc_std_block(block_group *bg) { +static block_desc *bc_alloc_std_block(block_group *bg, int expect_mprotect) { int this_block_size = bg->block_size; void *r = os_alloc_pages(this_block_size); block_desc *bd; @@ -105,6 +105,7 @@ static block_desc *bc_alloc_std_block(block_group *bg) { bg->block_size <<= 1; } + /* printf("BLOCK ALLOC %d %d\n", expect_mprotect, this_block_size); */ bd = (block_desc*) ofm_malloc_zero(sizeof(block_desc)); if (!bd) { os_free_pages(r, this_block_size); @@ -115,8 +116,6 @@ static block_desc *bc_alloc_std_block(block_group *bg) { bd->size = this_block_size; bd->used = 0; bd->group = bg; - bd->protect_map = (unsigned char *)ofm_malloc_zero(this_block_size >> (LOG_APAGE_SIZE + 3)); - bd->alloc_map = (unsigned char *)ofm_malloc_zero(this_block_size >> (LOG_APAGE_SIZE + 3)); gclist_init(&bd->gclist); /* printf("ALLOC BLOCK %p-%p size %li %li %li %p\n", bd->block, bd->block + bd->size, bd->size, APAGE_SIZE, bd->size / APAGE_SIZE, bd->free); */ @@ -133,6 +132,8 @@ static block_desc *bc_alloc_std_block(block_group *bg) { } } + bd->protect_map = (unsigned char *)ofm_malloc_zero(1 + (bd->size >> (LOG_APAGE_SIZE + 3))); + bd->alloc_map = (unsigned char *)ofm_malloc_zero(1 + (bd->size >> (LOG_APAGE_SIZE + 3))); /* setup free list of APAGE_SIZE sized pages inside block */ { @@ -147,10 +148,10 @@ static block_desc *bc_alloc_std_block(block_group *bg) { p = n; i++; } + if (p > pe) { p = (pfree_list *)((char *)p - (2 * APAGE_SIZE)); i--; } + else { p = (pfree_list *)((char *)p - APAGE_SIZE); } bd->totalcnt = i; bd->freecnt = i; - if (p > pe) { p = (p - (2 * APAGE_SIZE)); } - else { p = (p - APAGE_SIZE); } p->next = NULL; /* printf("ENDUP %p %p %p %i\n", n, p, p->next, i); */ } @@ -168,6 +169,7 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect tryagain: if (!gclist_is_empty(free_head)) { if (!gclist_first_item(free_head, block_desc*, gclist)->free) { + GC_ASSERT(!gclist_first_item(free_head, block_desc*, gclist)->freecnt); gclist_move(free_head->next, &bg->full); goto tryagain; } @@ -177,7 +179,7 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect #if BC_ASSERTS newbl = 1; #endif - bd = bc_alloc_std_block(bg); + bd = bc_alloc_std_block(bg, expect_mprotect); if (!bd) return NULL; gclist_add(free_head, &(bd->gclist)); (*size_diff) += bd->size; @@ -254,13 +256,14 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect } } -static ssize_t bc_free_std_block(block_desc *b) { +static ssize_t bc_free_std_block(block_desc *b, int expect_mprotect) { ssize_t size_diff = 0; + /* printf("BLOCK FREE %d %ld\n", expect_mprotect, b->size); */ gclist_del(&b->gclist); os_free_pages(b->block, b->size); size_diff -= b->size; - ofm_free(b->protect_map, b->size >> (LOG_APAGE_SIZE + 3)); - ofm_free(b->alloc_map, b->size >> (LOG_APAGE_SIZE + 3)); + ofm_free(b->protect_map, 1 + (b->size >> (LOG_APAGE_SIZE + 3))); + ofm_free(b->alloc_map, 1 + (b->size >> (LOG_APAGE_SIZE + 3))); ofm_free(b, sizeof(block_desc)); return size_diff; } @@ -339,6 +342,27 @@ static ssize_t block_cache_free_page(BlockCache* bc, void *p, size_t len, int ty } } +static void compute_compacts(block_group *bg) +{ + block_desc *b; + intptr_t avail, wanted; + + wanted = 0; + gclist_each_item(b, &bg->free, block_desc*, gclist) { + wanted += (b->totalcnt - b->freecnt); + } + + avail = 0; + gclist_each_item(b, &bg->free, block_desc*, gclist) { + if (avail > wanted) + b->want_compact = 1; + else { + b->want_compact = 0; + avail += b->totalcnt; + } + } +} + static int sort_full_to_empty(void *priv, GCList *a, GCList *b) { block_desc *ba = gclist_item(a, block_desc*, gclist); block_desc *bb = gclist_item(b, block_desc*, gclist); @@ -352,24 +376,28 @@ static int sort_full_to_empty(void *priv, GCList *a, GCList *b) { static void block_cache_prep_for_compaction(BlockCache* bc) { gclist_sort(NULL, &bc->atomic.free, sort_full_to_empty); gclist_sort(NULL, &bc->non_atomic.free, sort_full_to_empty); + + compute_compacts(&bc->atomic); + compute_compacts(&bc->non_atomic); + #if 0 { block_desc *b; + gclist_each_item(b, &bc->atomic.full, block_desc*, gclist) { + printf(" X ATOMIC _ %05li %03li %p\n", b->freecnt, b->totalcnt, b); } gclist_each_item(b, &bc->atomic.free, block_desc*, gclist) { - printf(" ATOMIC %05li %03li %p\n", b->freecnt, b->totalcnt, b); } + printf(" ATOMIC %d %05li %03li %p\n", b->want_compact, b->freecnt, b->totalcnt, b); } + gclist_each_item(b, &bc->non_atomic.full, block_desc*, gclist) { + printf(" X NONATOMIC _ %05li %03li %p\n", b->freecnt, b->totalcnt, b); } gclist_each_item(b, &bc->non_atomic.free, block_desc*, gclist) { - printf("NONATOMIC %03li %03li %p\n", b->freecnt, b->totalcnt, b); - } + printf(" NONATOMIC %d %05li %03li %p\n", b->want_compact, b->freecnt, b->totalcnt, b); } } #endif } static int block_cache_compact(void **src_block) { block_desc *b = *src_block; - if (b->freecnt > (b->totalcnt/2)) { - return 1; - } - return 0; + return b->want_compact; } static ssize_t block_cache_flush_freed_pages(BlockCache* bc) { @@ -379,10 +407,10 @@ static ssize_t block_cache_flush_freed_pages(BlockCache* bc) { ssize_t alloc_cache_size_diff = 0; gclist_each_item_safe(b, bn, &bc->atomic.free, block_desc*, gclist) { - if (b->freecnt == b->totalcnt) { size_diff += bc_free_std_block(b); } + if (b->freecnt == b->totalcnt) { size_diff += bc_free_std_block(b, 0); } } gclist_each_item_safe(b, bn, &bc->non_atomic.free, block_desc*, gclist) { - if (b->freecnt == b->totalcnt) { size_diff += bc_free_std_block(b); } + if (b->freecnt == b->totalcnt) { size_diff += bc_free_std_block(b, 1); } } alloc_cache_size_diff = alloc_cache_flush_freed_pages(bc->bigBlockCache); @@ -427,7 +455,7 @@ static void block_cache_queue_protect_range(BlockCache* bc, void *p, size_t len, { block_desc *b = (block_desc *)*src_block; b->in_queue = 1; - memset(b->protect_map, writeable ? 0 : 255, (b->size >> (LOG_APAGE_SIZE + 3))); + memset(b->protect_map, writeable ? 0 : 255, 1+(b->size >> (LOG_APAGE_SIZE + 3))); } return; break; diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index ea2328c3aa..42b0112352 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4310,6 +4310,13 @@ mpage *allocate_compact_target(NewGC *gc, mpage *work) return npage; } +static inline void gen1_free_mpage(PageMap pagemap, mpage *page) { + pagemap_remove(pagemap, page); + free_backtrace(page); + free_pages(GC_instance, page->addr, real_page_size(page), page_mmu_type(page), page_mmu_protectable(page), &page->mmu_src_block); + free_mpage(page); +} + /* Compact when 1/4 of the space between objects is unused: */ #define should_compact_page(lsize,tsize) (lsize < (tsize - PREFIX_SIZE - (APAGE_SIZE >> 2))) @@ -4322,8 +4329,9 @@ mpage *allocate_compact_target(NewGC *gc, mpage *work) inline static void do_heap_compact(NewGC *gc) { - int i; + int i, compact_count = 0, noncompact_count = 0; int tic_tock = gc->num_major_collects % 2; + mmu_prep_for_compaction(gc->mmu); #ifdef GC_MP_CNT mp_prev_compact_cnt = mp_compact_cnt; @@ -4353,6 +4361,7 @@ inline static void do_heap_compact(NewGC *gc) GCDEBUG((DEBUGOUTF, "Compacting page %p: new version at %p\n", work, npage)); + compact_count++; gc->need_fixup = 1; if (npage == work) { @@ -4413,7 +4422,8 @@ inline static void do_heap_compact(NewGC *gc) work->generation = AGE_VACATED; work = prev; - } else { + } else { + noncompact_count++; work = work->prev; } } else { @@ -4718,13 +4728,6 @@ static void repair_heap(NewGC *gc) gc->memory_in_use = memory_in_use; } -static inline void gen1_free_mpage(PageMap pagemap, mpage *page) { - pagemap_remove(pagemap, page); - free_backtrace(page); - free_pages(GC_instance, page->addr, real_page_size(page), page_mmu_type(page), page_mmu_protectable(page), &page->mmu_src_block); - free_mpage(page); -} - static inline void cleanup_vacated_pages(NewGC *gc) { mpage *pages = gc->release_pages; PageMap pagemap = gc->page_maps; From 68f8d632228adf07dc0bf4b3c194913471fae0de Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 15 Sep 2015 09:32:19 -0600 Subject: [PATCH 230/381] fix problem with traversing closures for GC This bug is an old one, in a sense, because travesing fields in a closure could have moved the prefix with earlier versions of the collector. It shows up now because we're changing fields one indirection closer. --- racket/src/racket/src/mzclpf_post.inc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/src/mzclpf_post.inc b/racket/src/racket/src/mzclpf_post.inc index 7fb3e2b4c5..6d92d6eaac 100644 --- a/racket/src/racket/src/mzclpf_post.inc +++ b/racket/src/racket/src/mzclpf_post.inc @@ -10,13 +10,16 @@ if (data) { /* GLOBAL ASSUMPTION: prefix is at the end of a closure */ Scheme_Prefix *pf = (Scheme_Prefix *)c->vals[closure_size - 1]; - + if (pf) { - /* Since pf hasn't been marked, we don't need a GC_resolve(): */ - int *use_bits = PREFIX_TO_USE_BITS(pf); + int *use_bits; uintptr_t map; int mark_stxes; + /* pf might have been marked via fields: */ + pf = (Scheme_Prefix *)GC_resolve2(pf, gc); + use_bits = PREFIX_TO_USE_BITS(pf); + if (!pf->next_final) { /* We're the first to look at this prefix... */ /* Add it to the chain of prefixes to finish after From 2616b0657069cc4ac8f8cd7c287d631a3956cb2b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 15 Sep 2015 09:33:54 -0600 Subject: [PATCH 231/381] fix problems with block-cache chunked mprotects The problems don't show up with the current use of the block cache, but repair mprotect tracking in case it matters in the future. --- racket/src/racket/gc2/block_cache.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/racket/src/racket/gc2/block_cache.c b/racket/src/racket/gc2/block_cache.c index eba6fe6f69..0f9ab8a729 100644 --- a/racket/src/racket/gc2/block_cache.c +++ b/racket/src/racket/gc2/block_cache.c @@ -200,8 +200,9 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect *src_block = bd; + GC_ASSERT(!BD_MAP_GET_BIT(bd->alloc_map, pos)); BD_MAP_SET_BIT(bd->alloc_map, pos); - + if (expect_mprotect) { if (BD_MAP_GET_BIT(bd->protect_map, pos)) { /* Unprotect a contiguous range of unallocated pages, @@ -209,11 +210,13 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect the range costs much less than multiple unprotect calls. */ int start_pos = pos, end_pos = pos + 1; + + BD_MAP_UNSET_BIT(bd->protect_map, pos); while (start_pos - && !BD_MAP_GET_BIT(bd->alloc_map, start_pos) - && BD_MAP_GET_BIT(bd->protect_map, start_pos)) { - BD_MAP_UNSET_BIT(bd->protect_map, start_pos); + && !BD_MAP_GET_BIT(bd->alloc_map, (start_pos-1)) + && BD_MAP_GET_BIT(bd->protect_map, (start_pos-1))) { --start_pos; + BD_MAP_UNSET_BIT(bd->protect_map, start_pos); } while ((end_pos < (bd->size >> LOG_APAGE_SIZE)) && !BD_MAP_GET_BIT(bd->alloc_map, end_pos) @@ -221,7 +224,6 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect BD_MAP_UNSET_BIT(bd->protect_map, end_pos); end_pos++; } - GC_MP_CNT_INC(mp_alloc_med_big_cnt); os_protect_pages((char *)p - ((pos - start_pos) * APAGE_SIZE), (end_pos - start_pos) * APAGE_SIZE, @@ -309,7 +311,7 @@ static ssize_t block_cache_free_page(BlockCache* bc, void *p, size_t len, int ty fl->dirty = 1; b->free = fl; GC_ASSERT(BD_MAP_GET_BIT(b->alloc_map, pos)); - BD_MAP_SET_BIT(b->alloc_map, pos); + BD_MAP_UNSET_BIT(b->alloc_map, pos); gclist_move(&b->gclist, free_head); b->freecnt++; #if BC_ASSERTS @@ -431,10 +433,15 @@ static void block_cache_protect_one_page(BlockCache* bc, void *p, size_t len, in int pos = BD_BLOCK_PTR_TO_POS(p, b); GC_ASSERT(pos >= 0); GC_ASSERT(pos < (b->size >> LOG_APAGE_SIZE)); - if (BD_MAP_GET_BIT(b->protect_map, pos)) { + GC_ASSERT(BD_MAP_GET_BIT(b->alloc_map, pos)); + if (writeable) { + GC_ASSERT(BD_MAP_GET_BIT(b->protect_map, pos)); BD_MAP_UNSET_BIT(b->protect_map, pos); - os_protect_pages(p, len, writeable); + } else { + GC_ASSERT(!BD_MAP_GET_BIT(b->protect_map, pos)); + BD_MAP_SET_BIT(b->protect_map, pos); } + os_protect_pages(p, len, writeable); } break; default: @@ -455,7 +462,6 @@ static void block_cache_queue_protect_range(BlockCache* bc, void *p, size_t len, { block_desc *b = (block_desc *)*src_block; b->in_queue = 1; - memset(b->protect_map, writeable ? 0 : 255, 1+(b->size >> (LOG_APAGE_SIZE + 3))); } return; break; @@ -474,12 +480,14 @@ static void block_cache_flush_protect_ranges(BlockCache* bc, int writeable) { if (b->in_queue) { b->in_queue = 0; page_range_add(bc->page_range, b->block, b->size, writeable); + memset(b->protect_map, writeable ? 0 : 255, 1+(b->size >> (LOG_APAGE_SIZE + 3))); } } gclist_each_item(b, &bg->free, block_desc*, gclist) { if (b->in_queue) { b->in_queue = 0; page_range_add(bc->page_range, b->block, b->size, writeable); + memset(b->protect_map, writeable ? 0 : 255, 1+(b->size >> (LOG_APAGE_SIZE + 3))); } } From 166d6fd8a34a6cbb0c969c802ab2912f63387309 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 15 Sep 2015 11:10:13 -0600 Subject: [PATCH 232/381] GC: fix block_cache assumptions Correct a mismatch for an internal API. --- racket/src/racket/gc2/block_cache.c | 15 ++++++++++----- racket/src/racket/gc2/newgc.c | 6 +++--- racket/src/racket/gc2/vm.c | 5 +++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/racket/src/racket/gc2/block_cache.c b/racket/src/racket/gc2/block_cache.c index 0f9ab8a729..f9f399a766 100644 --- a/racket/src/racket/gc2/block_cache.c +++ b/racket/src/racket/gc2/block_cache.c @@ -434,14 +434,19 @@ static void block_cache_protect_one_page(BlockCache* bc, void *p, size_t len, in GC_ASSERT(pos >= 0); GC_ASSERT(pos < (b->size >> LOG_APAGE_SIZE)); GC_ASSERT(BD_MAP_GET_BIT(b->alloc_map, pos)); + /* Since a queued mprotect affects more pages than the client can be sure of, + we have to accomodate redundant requests. */ if (writeable) { - GC_ASSERT(BD_MAP_GET_BIT(b->protect_map, pos)); - BD_MAP_UNSET_BIT(b->protect_map, pos); + if (BD_MAP_GET_BIT(b->protect_map, pos)) { + BD_MAP_UNSET_BIT(b->protect_map, pos); + os_protect_pages(p, len, writeable); + } } else { - GC_ASSERT(!BD_MAP_GET_BIT(b->protect_map, pos)); - BD_MAP_SET_BIT(b->protect_map, pos); + if (!BD_MAP_GET_BIT(b->protect_map, pos)) { + BD_MAP_SET_BIT(b->protect_map, pos); + os_protect_pages(p, len, writeable); + } } - os_protect_pages(p, len, writeable); } break; default: diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 42b0112352..8cc58863d1 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4225,7 +4225,7 @@ static void mark_backpointers(NewGC *gc) GC_ASSERT(work->back_pointers); if (work->mprotected) { - /* expected only if QUEUED_MPROTECT_IS_PROMISCUOUS && AGE_GEN_0_TO_GEN_HALF(gc) */ + /* expected only if QUEUED_MPROTECT_INFECTS_XXX && AGE_GEN_0_TO_GEN_HALF(gc) */ work->mprotected = 0; mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); } @@ -4909,7 +4909,7 @@ static void protect_old_pages(NewGC *gc) if (!page->mprotected && !page->back_pointers) { page->mprotected = 1; mmu_queue_write_protect_range(mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); - } else if (QUEUED_MPROTECT_IS_PROMISCUOUS) + } else if (QUEUED_MPROTECT_INFECTS_SMALL) page->mprotected = 1; } } @@ -4921,7 +4921,7 @@ static void protect_old_pages(NewGC *gc) if (!page->mprotected && !page->back_pointers) { page->mprotected = 1; mmu_queue_write_protect_range(mmu, page->addr, APAGE_SIZE, page_mmu_type(page), &page->mmu_src_block); - } else if (QUEUED_MPROTECT_IS_PROMISCUOUS) + } else if (QUEUED_MPROTECT_INFECTS_MED) page->mprotected = 1; } } diff --git a/racket/src/racket/gc2/vm.c b/racket/src/racket/gc2/vm.c index 92d22f7e40..53795283ce 100644 --- a/racket/src/racket/gc2/vm.c +++ b/racket/src/racket/gc2/vm.c @@ -28,10 +28,11 @@ enum { #ifdef USE_BLOCK_CACHE # define USE_ALLOC_CACHE -# define QUEUED_MPROTECT_IS_PROMISCUOUS 1 +# define QUEUED_MPROTECT_INFECTS_SMALL 1 #else -# define QUEUED_MPROTECT_IS_PROMISCUOUS 0 +# define QUEUED_MPROTECT_INFECTS_SMALL 0 #endif +#define QUEUED_MPROTECT_INFECTS_MED 0 /* Either USE_ALLOC_CACHE or OS_ALLOCATOR_NEEDS_ALIGNMENT must be enabled, unless the lower-level allocator's alignment matches From 0e35b5cfadc724651c778d44a2cd1a031e0379e3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 15 Sep 2015 11:33:43 -0600 Subject: [PATCH 233/381] fix misplaced flag The misplacement of `SCHEME_PRIM_SOMETIMES_INLINED` caused the optimizer to produce different results when the JIT is statically disabled, for example. --- racket/src/racket/include/scheme.h | 5 ----- racket/src/racket/src/schpriv.h | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 35d6cf7111..faa8842a2f 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -762,17 +762,12 @@ typedef struct Scheme_Offset_Cptr #define SCHEME_PRIM_STRUCT_TYPE_BROKEN_INDEXED_SETTER (32 | 128) #define SCHEME_PRIM_TYPE_PARAMETER 64 #define SCHEME_PRIM_TYPE_STRUCT_PROP_GETTER (64 | 128) -#define SCHEME_PRIM_SOMETIMES_INLINED (64 | 256) #define SCHEME_PRIM_STRUCT_TYPE_STRUCT_PROP_PRED (64 | 128 | 256) #define SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER 32 #define SCHEME_PRIM_STRUCT_TYPE_PRED (32 | 64) #define SCHEME_PRIM_PROC_FLAGS(x) (((Scheme_Prim_Proc_Header *)x)->flags) -#define SCHEME_PRIM_IS_SOMETIMES_INLINED(rator) \ - (((SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_OTHER_TYPE_MASK) == SCHEME_PRIM_SOMETIMES_INLINED) \ - || (SCHEME_PRIM_PROC_FLAGS(rator) & (SCHEME_PRIM_IS_UNARY_INLINED | SCHEME_PRIM_IS_BINARY_INLINED))) - typedef struct Scheme_Object *(Scheme_Prim)(int argc, Scheme_Object *argv[]); typedef struct Scheme_Object *(Scheme_Primitive_Closure_Proc)(int argc, struct Scheme_Object *argv[], Scheme_Object *p); diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 73f6f05afd..1ad35bdb3a 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -76,8 +76,9 @@ #define SCHEME_PRIM_WANTS_EXTFLONUM_THIRD (1 << 12) #define SCHEME_PRIM_IS_UNSAFE_NONALLOCATE (1 << 13) #define SCHEME_PRIM_ALWAYS_ESCAPES (1 << 14) +#define SCHEME_PRIM_SOMETIMES_INLINED (1 << 15) -#define SCHEME_PRIM_OPT_TYPE_SHIFT 15 +#define SCHEME_PRIM_OPT_TYPE_SHIFT 16 #define SCHEME_PRIM_OPT_TYPE_MASK (SCHEME_MAX_LOCAL_TYPE_MASK << SCHEME_PRIM_OPT_TYPE_SHIFT) #define SCHEME_PRIM_OPT_TYPE(x) ((x & SCHEME_PRIM_OPT_TYPE_MASK) >> SCHEME_PRIM_OPT_TYPE_SHIFT) From 21cc46e9159a8e2a115b1a05d30faff5b927ff4d Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Mon, 14 Sep 2015 00:30:54 -0300 Subject: [PATCH 234/381] Fix typo in test --- pkgs/racket-test-core/tests/racket/optimize.rktl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index c4a1ac3674..43a0abae7f 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -2010,7 +2010,7 @@ (define-values (x y) (values (car p) (cdr p))) (values y x)) '(lambda (p) - (values (#%unsafe-cdr p) (car p))) + (values (unsafe-cdr p) (car p))) #f) (test-comp '(lambda (p) (define-values (x y) (values (car p) (cdr p))) From bcfd19c90215cb94cce3cd8c2e6f3d2d9bfc55d3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 15 Sep 2015 19:40:07 -0600 Subject: [PATCH 235/381] GC: don't double-count phantom bytes --- racket/src/racket/gc2/newgc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 8cc58863d1..b4afb84306 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -1024,7 +1024,7 @@ static void collect_now(NewGC *gc, int major, int nomajor) static inline void gc_if_needed_account_alloc_size(NewGC *gc, size_t allocate_size) { - if((gc->gen0.current_size + allocate_size) >= gc->gen0.max_size) { + if((gc->gen0.current_size + gc->gen0_phantom_count + allocate_size) >= gc->gen0.max_size) { if (!gc->avoid_collection) collect_now(gc, 0, 0); } @@ -1292,7 +1292,7 @@ uintptr_t GC_make_jit_nursery_page(int count, uintptr_t *sz) { mpage *new_mpage; intptr_t size = count * THREAD_LOCAL_PAGE_SIZE; - if((gc->gen0.current_size + size) >= gc->gen0.max_size) { + if((gc->gen0.current_size + gc->gen0_phantom_count + size) >= gc->gen0.max_size) { if (!gc->avoid_collection) collect_now(gc, 0, 0); } @@ -1668,19 +1668,20 @@ int GC_allocate_phantom_bytes(void *pb, intptr_t request_size_bytes) page = pagemap_find_page(gc->page_maps, pb); - /* adjust `gc->memory_in_use', but protect against {over,under}flow: */ if (request_size_bytes < 0) { request_size_bytes = -request_size_bytes; - if (gc->memory_in_use > request_size_bytes) - gc->memory_in_use -= request_size_bytes; if (!page || (page->generation < AGE_GEN_1)) { if (gc->gen0_phantom_count > request_size_bytes) gc->gen0_phantom_count -= request_size_bytes; + } else { + if (gc->memory_in_use > request_size_bytes) + gc->memory_in_use -= request_size_bytes; } } else { if (!page || (page->generation < AGE_GEN_1)) gc->gen0_phantom_count = add_no_overflow(gc->gen0_phantom_count, request_size_bytes); - gc->memory_in_use = add_no_overflow(gc->memory_in_use, request_size_bytes); + else + gc->memory_in_use = add_no_overflow(gc->memory_in_use, request_size_bytes); } /* If we've allocated enough phantom bytes, then force a GC */ From 22cda632006470ccb6e3981ae2cf35584a59e9e5 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 28 Jul 2015 00:42:07 -0400 Subject: [PATCH 236/381] add string-startswith? and string-endswith? --- .../scribblings/reference/strings.scrbl | 14 +++++++++++++ .../racket-test-core/tests/racket/string.rktl | 19 ++++++++++++++++++ racket/collects/racket/string.rkt | 20 ++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/strings.scrbl b/pkgs/racket-doc/scribblings/reference/strings.scrbl index 6b16f7c236..eb991e8993 100644 --- a/pkgs/racket-doc/scribblings/reference/strings.scrbl +++ b/pkgs/racket-doc/scribblings/reference/strings.scrbl @@ -397,6 +397,13 @@ one between @racket[list] and @racket[list*]. ]} +@defproc[(string-endswith? [str string?] + [suffix string?]) + boolean?]{ + +Returns @racket[#t] if the second argument is a suffix of the first.} + + @defproc[(string-join [strs (listof string?)] [sep string? " "] [#:before-first before-first string? ""] [#:before-last before-last string? sep] @@ -459,6 +466,13 @@ replaced if @racket[all?] is @racket[#f]. ]} +@defproc[(string-startswith? [str string?] + [prefix string?]) + boolean?]{ + +Returns @racket[#t] if the second argument is a prefix of the first.} + + @defproc[(string-split [str string?] [sep (or/c string? regexp?) #px"\\s+"] [#:trim? trim? any/c #t] diff --git a/pkgs/racket-test-core/tests/racket/string.rktl b/pkgs/racket-test-core/tests/racket/string.rktl index cf0a959119..e0eec0caaa 100644 --- a/pkgs/racket-test-core/tests/racket/string.rktl +++ b/pkgs/racket-test-core/tests/racket/string.rktl @@ -490,4 +490,23 @@ (test "_1_ !!!" string-replace "_1_ _2_" str "!!!") ;verify that the new str is used ) +;; ---------- string-starts/endswith ---------- +(let () + (test #t string-startswith? "racket" "") + (test #t string-startswith? "racket" "r") + (test #t string-startswith? "racket" "rack") + (test #t string-startswith? "racket" "racket") + (test #t string-endswith? "racket" "") + (test #t string-endswith? "racket" "t") + (test #t string-endswith? "racket" "cket") + (test #t string-endswith? "racket" "racket") + (test #f string-startswith? "" "racket") + (test #f string-startswith? "racket" "R") + (test #f string-startswith? "racket" "rak") + (test #f string-startswith? "racket" "racket2") + (test #f string-endswith? "" "racket") + (test #f string-endswith? "racket" "T") + (test #f string-endswith? "racket" "r") + (test #f string-endswith? "racket" "kat")) + (report-errs) diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index 6e8ad8d18b..3d0db26729 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -6,7 +6,9 @@ string-normalize-spaces string-split string-replace - non-empty-string?) + non-empty-string? + string-startswith? + string-endswith?) (define string-append* (case-lambda [(strs) (apply string-append strs)] ; optimize common cases @@ -138,3 +140,19 @@ (define (non-empty-string? x) (and (string? x) (not (zero? (string-length x))))) + +(define (string-startswith? str prefix) + (and + (<= (string-length prefix) (string-length str)) + (for/and ([c1 (in-string str)] + [c2 (in-string prefix)]) + (char=? c1 c2)))) + +(define (string-endswith? str suffix) + ;; Skip all but the last `suffix` characters of `str` + (define offset (- (string-length str) (string-length suffix))) + (and + (not (negative? offset)) + (for/and ([c1 (in-string str offset)] + [c2 (in-string suffix)]) + (char=? c1 c2)))) From 85e5db38fb742da47427994f4438b75c42247119 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 28 Jul 2015 13:23:26 -0400 Subject: [PATCH 237/381] renamed string-startswith/endswith to string-prefix/suffix --- .../scribblings/reference/strings.scrbl | 28 +++++++-------- .../racket-test-core/tests/racket/string.rktl | 35 ++++++++++--------- racket/collects/racket/string.rkt | 9 +++-- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/strings.scrbl b/pkgs/racket-doc/scribblings/reference/strings.scrbl index eb991e8993..6da9befe99 100644 --- a/pkgs/racket-doc/scribblings/reference/strings.scrbl +++ b/pkgs/racket-doc/scribblings/reference/strings.scrbl @@ -397,13 +397,6 @@ one between @racket[list] and @racket[list*]. ]} -@defproc[(string-endswith? [str string?] - [suffix string?]) - boolean?]{ - -Returns @racket[#t] if the second argument is a suffix of the first.} - - @defproc[(string-join [strs (listof string?)] [sep string? " "] [#:before-first before-first string? ""] [#:before-last before-last string? sep] @@ -448,6 +441,13 @@ The result of @racket[(string-normalize-spaces str sep space)] is the same as @racket[(string-join (string-split str sep ....) space)].} +@defproc[(string-prefix? [str string?] + [prefix string?]) + boolean?]{ + +Returns @racket[#t] if the second argument is a prefix of the first.} + + @defproc[(string-replace [str string?] [from (or/c string? regexp?)] [to string?] @@ -466,13 +466,6 @@ replaced if @racket[all?] is @racket[#f]. ]} -@defproc[(string-startswith? [str string?] - [prefix string?]) - boolean?]{ - -Returns @racket[#t] if the second argument is a prefix of the first.} - - @defproc[(string-split [str string?] [sep (or/c string? regexp?) #px"\\s+"] [#:trim? trim? any/c #t] @@ -497,6 +490,13 @@ and @racket[repeat?] controls matching repeated sequences. ]} +@defproc[(string-suffix? [str string?] + [suffix string?]) + boolean?]{ + +Returns @racket[#t] if the second argument is a suffix of the first.} + + @defproc[(string-trim [str string?] [sep (or/c string? regexp?) #px"\\s+"] [#:left? left? any/c #t] diff --git a/pkgs/racket-test-core/tests/racket/string.rktl b/pkgs/racket-test-core/tests/racket/string.rktl index e0eec0caaa..07cd8c4b9a 100644 --- a/pkgs/racket-test-core/tests/racket/string.rktl +++ b/pkgs/racket-test-core/tests/racket/string.rktl @@ -490,23 +490,24 @@ (test "_1_ !!!" string-replace "_1_ _2_" str "!!!") ;verify that the new str is used ) -;; ---------- string-starts/endswith ---------- +;; ---------- string-prefix?/suffix? ---------- (let () - (test #t string-startswith? "racket" "") - (test #t string-startswith? "racket" "r") - (test #t string-startswith? "racket" "rack") - (test #t string-startswith? "racket" "racket") - (test #t string-endswith? "racket" "") - (test #t string-endswith? "racket" "t") - (test #t string-endswith? "racket" "cket") - (test #t string-endswith? "racket" "racket") - (test #f string-startswith? "" "racket") - (test #f string-startswith? "racket" "R") - (test #f string-startswith? "racket" "rak") - (test #f string-startswith? "racket" "racket2") - (test #f string-endswith? "" "racket") - (test #f string-endswith? "racket" "T") - (test #f string-endswith? "racket" "r") - (test #f string-endswith? "racket" "kat")) + (test #t string-prefix? "racket" "") + (test #t string-prefix? "racket" "r") + (test #t string-prefix? "racket" "rack") + (test #t string-prefix? "racket" "racket") + (test #t string-suffix? "racket" "") + (test #t string-suffix? "racket" "t") + (test #t string-suffix? "racket" "cket") + (test #t string-suffix? "racket" "racket") + ;; -------------------- + (test #f string-prefix? "" "racket") + (test #f string-prefix? "racket" "R") + (test #f string-prefix? "racket" "rak") + (test #f string-prefix? "racket" "racket2") + (test #f string-suffix? "" "racket") + (test #f string-suffix? "racket" "T") + (test #f string-suffix? "racket" "r") + (test #f string-suffix? "racket" "kat")) (report-errs) diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index 3d0db26729..31b8df1fe5 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -7,8 +7,8 @@ string-split string-replace non-empty-string? - string-startswith? - string-endswith?) + string-prefix? + string-suffix?) (define string-append* (case-lambda [(strs) (apply string-append strs)] ; optimize common cases @@ -141,15 +141,14 @@ (define (non-empty-string? x) (and (string? x) (not (zero? (string-length x))))) -(define (string-startswith? str prefix) +(define (string-prefix? str prefix) (and (<= (string-length prefix) (string-length str)) (for/and ([c1 (in-string str)] [c2 (in-string prefix)]) (char=? c1 c2)))) -(define (string-endswith? str suffix) - ;; Skip all but the last `suffix` characters of `str` +(define (string-suffix? str suffix) (define offset (- (string-length str) (string-length suffix))) (and (not (negative? offset)) From 3fc4a64759ece198375a93e49a38f7a19f460f96 Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 16 Aug 2015 17:27:24 -0400 Subject: [PATCH 238/381] faster implementation of prefix/suffix --- racket/collects/racket/string.rkt | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index 31b8df1fe5..dfeb5f82bf 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -142,16 +142,20 @@ (and (string? x) (not (zero? (string-length x))))) (define (string-prefix? str prefix) - (and - (<= (string-length prefix) (string-length str)) - (for/and ([c1 (in-string str)] - [c2 (in-string prefix)]) - (char=? c1 c2)))) + (define l1 (string-length str)) + (define l2 (string-length prefix)) + (let loop ([i 0]) + (cond + [(= l2 i) #t] ;; Finished reading all chars in prefix + [(= l1 i) #f] ;; Prefix is longer than string + [else (and (char=? (string-ref str i) (string-ref prefix i)) + (loop (add1 i)))]))) (define (string-suffix? str suffix) - (define offset (- (string-length str) (string-length suffix))) - (and - (not (negative? offset)) - (for/and ([c1 (in-string str offset)] - [c2 (in-string suffix)]) - (char=? c1 c2)))) + (define l2 (string-length suffix)) + (define offset (- (string-length str) l2)) + (and (not (negative? offset)) ;; Suffix isn't longer than string + (let loop ([i+o offset] [i 0]) + (or (= i l2) + (and (char=? (string-ref str i+o) (string-ref suffix i)) + (loop (add1 i+o) (add1 i))))))) From ae5b980e07a0db855afb54265f02d4d1e0961f9d Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 16 Sep 2015 11:15:47 -0500 Subject: [PATCH 239/381] Add `string-contains?`. From Ben Greenman. --- pkgs/racket-test-core/tests/racket/string.rktl | 13 +++++++++++++ racket/collects/racket/string.rkt | 17 ++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/string.rktl b/pkgs/racket-test-core/tests/racket/string.rktl index 07cd8c4b9a..2eeabedf14 100644 --- a/pkgs/racket-test-core/tests/racket/string.rktl +++ b/pkgs/racket-test-core/tests/racket/string.rktl @@ -510,4 +510,17 @@ (test #f string-suffix? "racket" "r") (test #f string-suffix? "racket" "kat")) +;; ---------- string-contains? ---------- + +(let () + (test #t string-contains? "racket" "racket") + (test #t string-contains? "racket" "cket") + (test #t string-contains? "racket" "acke") + (test #t string-contains? "racket" "t") + (test #t string-contains? "racket" "") + (test #f string-contains? "racket" "b") + (test #f string-contains? "racket" "R") + (test #f string-contains? "racket" "kc") + (test #f string-contains? "racket" "racketr")) + (report-errs) diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index dfeb5f82bf..b42b68b627 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -8,7 +8,8 @@ string-replace non-empty-string? string-prefix? - string-suffix?) + string-suffix? + string-contains?) (define string-append* (case-lambda [(strs) (apply string-append strs)] ; optimize common cases @@ -159,3 +160,17 @@ (or (= i l2) (and (char=? (string-ref str i+o) (string-ref suffix i)) (loop (add1 i+o) (add1 i))))))) + +(define (string-contains? str sub) + (define L1 (string-length str)) + (define L2 (string-length sub)) + (define d (- L1 L2)) + (or (zero? L2) + (let loop ([start 0]) + (and (<= start d) + (or (let loop2 ([offset 0]) + (or (= offset L2) + (and (char=? (string-ref str (+ start offset)) + (string-ref sub offset)) + (loop2 (add1 offset))))) + (loop (add1 start))))))) From 2b1202a6a66a19e8717e9682d6a5c9ccbc083caa Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 16 Sep 2015 11:25:48 -0500 Subject: [PATCH 240/381] Add error checking to new string functions. --- racket/collects/racket/string.rkt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/racket/collects/racket/string.rkt b/racket/collects/racket/string.rkt index b42b68b627..d4f51511f6 100644 --- a/racket/collects/racket/string.rkt +++ b/racket/collects/racket/string.rkt @@ -143,6 +143,10 @@ (and (string? x) (not (zero? (string-length x))))) (define (string-prefix? str prefix) + (unless (string? str) + (raise-argument-error 'string-prefix? "string?" str)) + (unless (string? prefix) + (raise-argument-error 'string-prefix? "string?" prefix)) (define l1 (string-length str)) (define l2 (string-length prefix)) (let loop ([i 0]) @@ -153,6 +157,10 @@ (loop (add1 i)))]))) (define (string-suffix? str suffix) + (unless (string? str) + (raise-argument-error 'string-suffix? "string?" str)) + (unless (string? suffix) + (raise-argument-error 'string-suffix? "string?" suffix)) (define l2 (string-length suffix)) (define offset (- (string-length str) l2)) (and (not (negative? offset)) ;; Suffix isn't longer than string @@ -162,6 +170,10 @@ (loop (add1 i+o) (add1 i))))))) (define (string-contains? str sub) + (unless (string? str) + (raise-argument-error 'string-contains? "string?" str)) + (unless (string? sub) + (raise-argument-error 'string-prefix? "string?" sub)) (define L1 (string-length str)) (define L2 (string-length sub)) (define d (- L1 L2)) From 4522d2167ace8fd544dab8854b9bfe2d0da13883 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 16 Sep 2015 11:26:00 -0500 Subject: [PATCH 241/381] Merge docs for new string functions. --- .../scribblings/reference/strings.scrbl | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/strings.scrbl b/pkgs/racket-doc/scribblings/reference/strings.scrbl index 6da9befe99..8df20e525e 100644 --- a/pkgs/racket-doc/scribblings/reference/strings.scrbl +++ b/pkgs/racket-doc/scribblings/reference/strings.scrbl @@ -441,13 +441,6 @@ The result of @racket[(string-normalize-spaces str sep space)] is the same as @racket[(string-join (string-split str sep ....) space)].} -@defproc[(string-prefix? [str string?] - [prefix string?]) - boolean?]{ - -Returns @racket[#t] if the second argument is a prefix of the first.} - - @defproc[(string-replace [str string?] [from (or/c string? regexp?)] [to string?] @@ -490,13 +483,6 @@ and @racket[repeat?] controls matching repeated sequences. ]} -@defproc[(string-suffix? [str string?] - [suffix string?]) - boolean?]{ - -Returns @racket[#t] if the second argument is a suffix of the first.} - - @defproc[(string-trim [str string?] [sep (or/c string? regexp?) #px"\\s+"] [#:left? left? any/c #t] @@ -527,6 +513,23 @@ returns @racket[#f] otherwise. @history[#:added "6.2.900.15"]{} } +@deftogether[( +@defproc[(string-contains? [s string?] [contained string?]) boolean?] +@defproc[(string-prefix? [s string?] [prefix string?]) boolean?] +@defproc[(string-suffix? [s string?] [suffix string?]) boolean?])]{ +Checks whether @racket[s] includes at any location, start with, or ends with +the second argument, respectively. + +@mz-examples[#:eval string-eval + (string-prefix? "Racket" "R") + (string-prefix? "Jacket" "R") + (string-suffix? "Racket" "et") + (string-contains? "Racket" "ack") +] + +@history[#:added "6.2.900.17"]{} +} + @; ---------------------------------------- @include-section["format.scrbl"] From 17b96cc5a1dacfdf0c321437d7050a18fe0a4494 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 16 Sep 2015 13:24:32 -0500 Subject: [PATCH 242/381] Remove unused import. --- pkgs/racket-test/tests/match/examples.rkt | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/racket-test/tests/match/examples.rkt b/pkgs/racket-test/tests/match/examples.rkt index 036aa9bbd9..e9a0c97921 100644 --- a/pkgs/racket-test/tests/match/examples.rkt +++ b/pkgs/racket-test/tests/match/examples.rkt @@ -6,7 +6,6 @@ (only-in racket/list split-at) (for-syntax scheme/base) (prefix-in m: mzlib/match) - (only-in srfi/13 string-contains) rackunit) (define-syntax (comp stx) From 9c123172fa4372dd7f278182bfaa646e0e01de2e Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 16 Sep 2015 13:53:52 -0500 Subject: [PATCH 243/381] Move srfi-related tests to srfi-test. --- pkgs/racket-test/info.rkt | 1 - .../tests/racket/srfi-1-collide.rkt | 3 - pkgs/racket-test/tests/racket/srfi-14.rkt | 516 ------------------ 3 files changed, 520 deletions(-) delete mode 100644 pkgs/racket-test/tests/racket/srfi-1-collide.rkt delete mode 100644 pkgs/racket-test/tests/racket/srfi-14.rkt diff --git a/pkgs/racket-test/info.rkt b/pkgs/racket-test/info.rkt index 8cb93d6e80..1ebe644ba7 100644 --- a/pkgs/racket-test/info.rkt +++ b/pkgs/racket-test/info.rkt @@ -27,7 +27,6 @@ (define build-deps '("racket-index" "scheme-lib" - "srfi-lite-lib" "base" "data-lib")) diff --git a/pkgs/racket-test/tests/racket/srfi-1-collide.rkt b/pkgs/racket-test/tests/racket/srfi-1-collide.rkt deleted file mode 100644 index fcbb070a6e..0000000000 --- a/pkgs/racket-test/tests/racket/srfi-1-collide.rkt +++ /dev/null @@ -1,3 +0,0 @@ -#lang racket/base -;; ---------- check no collisions with srfi/1 ---------- -(require scheme/base srfi/1/list) diff --git a/pkgs/racket-test/tests/racket/srfi-14.rkt b/pkgs/racket-test/tests/racket/srfi-14.rkt deleted file mode 100644 index d46fbf6cc3..0000000000 --- a/pkgs/racket-test/tests/racket/srfi-14.rkt +++ /dev/null @@ -1,516 +0,0 @@ -#lang racket/base - -(require rackunit) -(require srfi/14/char-set) - -(define-syntax test - (syntax-rules () - [(_ #t p? args ...) (check-true (p? args ...))] - [(_ #f p? args ...) (check-false (p? args ...))] - [(_ e args ...) (check-equal? e (args ...))])) - -(define-syntax-rule (err/rt-test e) (check-exn exn:fail? (λ () e))) - -;; NOTE: tests assume that ! functions are actually functional - -;; Check char sets ---------------------------------------- - -(test #t char-set-contains? char-set:lower-case #\a) -(test #f char-set-contains? char-set:lower-case #\A) -(test #t char-set-contains? char-set:lower-case #\u00E0) -(test #f char-set-contains? char-set:lower-case #\u00C2) -(test #t char-set-contains? char-set:lower-case #\u00B5) - -(test #t char-set-contains? char-set:upper-case #\A) -(test #f char-set-contains? char-set:upper-case #\a) -(test #t char-set-contains? char-set:upper-case #\u00C2) -(test #f char-set-contains? char-set:upper-case #\u00E0) - -(test #t char-set-contains? char-set:title-case #\u01C5) -(test #t char-set-contains? char-set:title-case #\u1FA8) -(test #f char-set-contains? char-set:title-case #\a) -(test #f char-set-contains? char-set:title-case #\A) - -(test #t char-set-contains? char-set:letter #\a) -(test #t char-set-contains? char-set:letter #\A) -(test #f char-set-contains? char-set:letter #\1) -(test #t char-set-contains? char-set:letter #\u00AA) -(test #t char-set-contains? char-set:letter #\u00BA) - -(test #f char-set-every (lambda (c) (char-set-contains? char-set:lower-case c)) char-set:letter) -(test #t char-set-any (lambda (c) (char-set-contains? char-set:lower-case c)) char-set:letter) -(test #f char-set-every (lambda (c) (char-set-contains? char-set:upper-case c)) char-set:letter) -(test #t char-set-any (lambda (c) (char-set-contains? char-set:upper-case c)) char-set:letter) -;; Not true? -;; (test #t char-set<= char-set:letter (char-set-union char-set:lower-case char-set:upper-case char-set:title-case)) - -(test #t char-set-contains? char-set:digit #\1) -(test #f char-set-contains? char-set:digit #\a) - -(test #t char-set-contains? char-set:hex-digit #\1) -(test #t char-set-contains? char-set:hex-digit #\a) -(test #t char-set-contains? char-set:hex-digit #\A) -(test #f char-set-contains? char-set:hex-digit #\g) - -(test #t char-set-contains? char-set:letter+digit #\1) -(test #t char-set-contains? char-set:letter+digit #\a) -(test #t char-set-contains? char-set:letter+digit #\z) -(test #t char-set-contains? char-set:letter+digit #\A) -(test #t char-set-contains? char-set:letter+digit #\Z) - -;; As of Unicode 5.0: 93217 -;; As of Unicode 7.0: -(test 104077 char-set-size char-set:letter) - -(test #t char-set= char-set:letter+digit (char-set-union char-set:letter char-set:digit)) -;; Slow!: -;; (test #t char-set-every (lambda (c) (char-set-contains? char-set:letter+digit c)) char-set:letter) -;; Slow!: -;; (test #t char-set-every (lambda (c) (char-set-contains? char-set:letter+digit c)) char-set:digit) -(test #f char-set-every (lambda (c) (char-set-contains? char-set:letter c)) char-set:letter+digit) -(test #f char-set-every (lambda (c) (char-set-contains? char-set:digit c)) char-set:letter+digit) -(test #t char-set-any (lambda (c) (char-set-contains? char-set:letter c)) char-set:letter+digit) - -(define char-set:latin-1 (ucs-range->char-set 0 256)) - -(test #t char-set= - (char-set-intersection char-set:graphic char-set:latin-1) - (char-set-intersection (char-set-union char-set:letter char-set:digit char-set:punctuation char-set:symbol - ;; 1/4, 1/2, and 3/4: - (char-set #\uBC #\uBD #\uBE)) - char-set:latin-1)) - -(test #t char-set= char-set:printing (char-set-union char-set:graphic char-set:whitespace)) - -(test #t char-set-contains? char-set:whitespace #\u0009) -(test #t char-set-contains? char-set:whitespace #\u000D) -(test #f char-set-contains? char-set:whitespace #\a) - -(test #t char-set= char-set:iso-control - (char-set-union (ucs-range->char-set #x0000 #x0020) - (ucs-range->char-set #x007F #x00A0))) - -(test #t char-set-contains? char-set:punctuation #\!) -(test #t char-set-contains? char-set:punctuation #\u00A1) -(test #f char-set-contains? char-set:punctuation #\a) - -(test #t char-set-contains? char-set:symbol #\$) -(test #t char-set-contains? char-set:symbol #\u00A2) -(test #f char-set-contains? char-set:symbol #\a) - -(test #t char-set-contains? char-set:blank #\space) -(test #t char-set-contains? char-set:blank #\u3000) -(test #f char-set-contains? char-set:blank #\a) - -;; General procedures ---------------------------------------- - -(test #t char-set= char-set:letter char-set:letter char-set:letter) -(test #f char-set= char-set:letter char-set:digit) -(test #f char-set= char-set:letter char-set:letter char-set:digit) -(test #f char-set= char-set:letter char-set:digit char-set:letter) - -(test #t char-set<= char-set:graphic char-set:printing) -(test #f char-set<= char-set:printing char-set:graphic) -(test #t char-set<= char-set:graphic char-set:printing char-set:full) -(test #f char-set<= char-set:graphic char-set:full char-set:printing) - -(test (char-set-hash char-set:graphic) char-set-hash char-set:graphic) - -;; Iterating over character sets ---------------------------------------- - -;; As of Unicode 5.0: 388 -;; As of Unicode 7.0: -(test 668 char-set-size char-set:digit) - -(test #t char-set= - char-set:digit - (list->char-set - (let loop ([c (char-set-cursor char-set:digit)][l null]) - (if (end-of-char-set? c) - l - (loop (char-set-cursor-next char-set:digit c) - (cons (char-set-ref char-set:digit c) - l)))))) - -(test #t char-set= - (ucs-range->char-set 10 20) - (char-set-unfold (lambda (x) (= x 20)) integer->char add1 10)) -(test #t char-set= - (ucs-range->char-set 10 21) - (char-set-unfold (lambda (x) (= x 20)) integer->char add1 10 (char-set #\u14))) -(test #t char-set= - (ucs-range->char-set 10 20) - (char-set-unfold! (lambda (x) (= x 20)) integer->char add1 10 char-set:empty)) - -(test #t char-set= char-set:digit - (let ([cs char-set:empty]) - (char-set-for-each - (lambda (c) - (set! cs (char-set-adjoin cs c))) - char-set:digit) - cs)) - -(test #t char-set= char-set:digit - (char-set-map - (lambda (c) c) - char-set:digit)) -(test #t char-set= char-set:digit - (char-set-map - (lambda (c) c) - char-set:digit)) -(test #t char-set= (char-set-adjoin char-set:digit #\A) - (char-set-union - (char-set-map - (lambda (c) c) - char-set:digit) - (char-set #\A))) - -;; Creating character sets ---------------------------------------- - -(test #t char-set= char-set:digit (char-set-copy char-set:digit)) - -(let ([abc (char-set #\a #\b #\c)]) - (test #t char-set= abc (char-set #\c #\a #\b)) - (test #t char-set= abc (string->char-set "cba")) - (test #t char-set= abc (string->char-set! "cba" char-set:empty)) - (test #t char-set= abc (string->char-set "cb" (char-set #\a))) - (test #t char-set= (char-set #\b) (char-set-filter (lambda (c) (char=? c #\b)) abc)) - (test #t char-set= (char-set #\b) (char-set-filter (lambda (c) (char=? c #\b)) abc char-set:empty)) - (test #t char-set= (char-set #\b) (char-set-filter! (lambda (c) (char=? c #\b)) abc char-set:empty)) - (test #t char-set= abc (->char-set "abc")) - (test #t char-set= abc (->char-set abc)) - (test #t char-set= (char-set #\a) (->char-set #\a))) - -(test #t char-set= - (ucs-range->char-set 0 #x20000) - (char-set-union (ucs-range->char-set 0 #xD800) - (ucs-range->char-set #xE000 #x20000))) -(test #t char-set= - (ucs-range->char-set 0 #xD801) - (ucs-range->char-set 0 #xD800)) -(test #t char-set= - (ucs-range->char-set 0 #xDFFF) - (ucs-range->char-set 0 #xD800)) -(test #t char-set= - (ucs-range->char-set #xD800 #xD810) - char-set:empty) -(test #t char-set= - (ucs-range->char-set #xD810 #xE000) - char-set:empty) -(test #t char-set= - (ucs-range->char-set #xE000 #xE001) - (ucs-range->char-set #xD810 #xE001)) -(test #t char-set= - (ucs-range->char-set #xD7FF #xE001) - (char-set #\uD7FF #\uE000)) - -(err/rt-test (ucs-range->char-set -1 10)) -(err/rt-test (ucs-range->char-set 2 2)) -(err/rt-test (ucs-range->char-set 2 1)) -(err/rt-test (ucs-range->char-set 0 #x300000)) -(err/rt-test (ucs-range->char-set #x300000 #x300001)) - -;; Querying character sets ------------------------------ - -(test 3 char-set-count (lambda (x) (char<=? #\0 x #\2)) char-set:digit) - -(test #t char-set= char-set:digit (list->char-set (char-set->list char-set:digit))) -(test #t char-set= char-set:digit (list->char-set (char-set->list char-set:digit) char-set:empty)) -(test #t char-set= char-set:digit (list->char-set! (char-set->list char-set:digit) char-set:empty)) -(test #t char-set= char-set:digit (string->char-set (char-set->string char-set:digit))) - -;; Character-set algebra ---------------------------------------- - -(let* ([cs1 (char-set #\U #\t #\a #\h)] - [cs2 (char-set-union cs1 (char-set #\S #\L #\C))]) - (test #t char-set= cs2 (char-set-adjoin cs1 #\S #\L #\C)) - (test #t char-set= cs2 (char-set-adjoin! cs1 #\S #\L #\C)) - (test #t char-set= (char-set-delete cs2 #\S #\L #\C) cs1) - (test #t char-set= (char-set-delete! cs2 #\S #\L #\C) cs1) - - (test #t char-set= char-set:empty (char-set-union)) - (test #t char-set= char-set:full (char-set-intersection)) - (test #t char-set= char-set:empty (char-set-xor)) - (test #t char-set= char-set:digit (char-set-union char-set:digit)) - (test #t char-set= char-set:digit (char-set-intersection char-set:digit)) - (test #t char-set= char-set:digit (char-set-difference char-set:digit)) - (test #t char-set= char-set:digit (char-set-xor char-set:digit)) - - (let ([go - (lambda (char-set-union) - (test #t char-set= cs1 (char-set-union (char-set #\U #\t #\a #\h))) - (test #t char-set= cs1 (char-set-union (char-set #\U #\t) (char-set #\a #\h))) - (test #t char-set= cs1 (char-set-union (char-set #\U) (char-set #\t #\a) (char-set #\h))))]) - (go char-set-union) - (go char-set-union!)) - - (let ([go - (lambda (char-set-intersect) - (test #t char-set= cs1 (char-set-intersect (char-set #\U #\t #\a #\h))) - (test #t char-set= cs1 (char-set-intersect (char-set #\U #\t #\a #\h #\v) (char-set #\U #\t #\a #\h #\w))) - (test #t char-set= cs1 (char-set-intersect (char-set #\U #\t #\a #\h #\v) - (char-set #\U #\t #\a #\h #\w) - (char-set #\a #\b #\U #\t #\a #\h #\w))))]) - (go char-set-intersection) - (go char-set-intersection!)) - - (let ([go - (lambda (char-set-diff) - (test #t char-set= cs1 (char-set-diff (char-set #\U #\t #\a #\h #\v) - (char-set #\v #\b))) - (test #t char-set= cs1 (char-set-diff (char-set #\U #\t #\a #\h #\v #\w) - (char-set #\v #\b) - (char-set #\w))) - (test #t char-set= cs1 (char-set-diff (char-set #\U #\t #\a #\h))))]) - (go char-set-difference) - (go char-set-difference!) - (go char-set-difference!)) - - (let ([go - (lambda (char-set-xor) - (test #t char-set= cs1 (char-set-xor (char-set #\U #\t #\a #\v) - (char-set #\v #\h))) - (test #t char-set= cs1 (char-set-xor (char-set #\U #\h #\v #\w) - (char-set #\v #\a #\b) - (char-set #\t #\w #\b))))]) - (go char-set-xor) - (go char-set-xor!)) - - (let ([go - (lambda (char-set-diff+i) - (test #t andmap char-set= (list cs1 (char-set-union)) - (call-with-values - (lambda () - (char-set-diff+i (char-set #\U #\t #\a #\h))) - list)) - (test #t andmap char-set= (list cs1 (char-set #\v)) - (call-with-values - (lambda () - (char-set-diff+i (char-set #\U #\t #\a #\h #\v) - (char-set #\v #\b))) - list)) - (test #t andmap char-set= (list cs1 char-set:empty) - (call-with-values - (lambda () - (char-set-diff+i (char-set #\U #\t #\a #\h #\v #\w) - (char-set #\v #\b) - (char-set #\w))) - list)))]) - (go char-set-diff+intersection) - (go char-set-diff+intersection) - (go char-set-diff+intersection!)) - - ) - -;; ---------------------------------------- - - -;;; This is a regression testing suite for the SRFI-14 char-set library. -;;; Olin Shivers - -(letrec-syntax ((tests (syntax-rules () - ((_ tst ...) - (begin (one-test tst) ...)))) - (one-test (syntax-rules (let) - ((_ (let . rest)) - (check-true (let . rest))) - ((_ (op arg ...)) - (check-true (op arg ...)))))) - (let ((vowel? (lambda (c) (member c '(#\a #\e #\i #\o #\u))))) - - (tests - (not (char-set? 5)) - - (char-set? (char-set #\a #\e #\i #\o #\u)) - - (char-set=) - (char-set= (char-set)) - - (char-set= (char-set #\a #\e #\i #\o #\u) - (string->char-set "ioeauaiii")) - - (not (char-set= (char-set #\e #\i #\o #\u) - (string->char-set "ioeauaiii"))) - - (char-set<=) - (char-set<= (char-set)) - - (char-set<= (char-set #\a #\e #\i #\o #\u) - (string->char-set "ioeauaiii")) - - (char-set<= (char-set #\e #\i #\o #\u) - (string->char-set "ioeauaiii")) - - (<= 0 (char-set-hash char-set:graphic 100) 99) - - (= 4 (char-set-fold (lambda (c i) (+ i 1)) 0 - (char-set #\e #\i #\o #\u #\e #\e))) - - (char-set= (string->char-set "eiaou2468013579999") - (char-set-intersection - (char-set-unfold null? car cdr '(#\a #\e #\i #\o #\u #\u #\u) - char-set:digit) - char-set:ascii)) - - (char-set= (string->char-set "eiaou246801357999") - (char-set-unfold! null? car cdr '(#\a #\e #\i #\o #\u) - (string->char-set "0123456789"))) - - (not (char-set= (string->char-set "eiaou246801357") - (char-set-unfold! null? car cdr '(#\a #\e #\i #\o #\u) - (string->char-set "0123456789")))) - - (let ((cs (string->char-set "0123456789"))) - (char-set-for-each (lambda (c) (set! cs (char-set-delete cs c))) - (string->char-set "02468000")) - (char-set= cs (string->char-set "97531"))) - - (not (let ((cs (string->char-set "0123456789"))) - (char-set-for-each (lambda (c) (set! cs (char-set-delete cs c))) - (string->char-set "02468")) - (char-set= cs (string->char-set "7531")))) - - (char-set= (char-set-map char-upcase (string->char-set "aeiou")) - (string->char-set "IOUAEEEE")) - - (not (char-set= (char-set-map char-upcase (string->char-set "aeiou")) - (string->char-set "OUAEEEE"))) - - (char-set= (char-set-copy (string->char-set "aeiou")) - (string->char-set "aeiou")) - - (char-set= (char-set #\x #\y) (string->char-set "xy")) - (not (char-set= (char-set #\x #\y #\z) (string->char-set "xy"))) - - (char-set= (string->char-set "xy") (list->char-set '(#\x #\y))) - (not (char-set= (string->char-set "axy") (list->char-set '(#\x #\y)))) - - (char-set= (string->char-set "xy12345") - (list->char-set '(#\x #\y) (string->char-set "12345"))) - (not (char-set= (string->char-set "y12345") - (list->char-set '(#\x #\y) (string->char-set "12345")))) - - (char-set= (string->char-set "xy12345") - (list->char-set! '(#\x #\y) (string->char-set "12345"))) - (not (char-set= (string->char-set "y12345") - (list->char-set! '(#\x #\y) (string->char-set "12345")))) - - (char-set= (string->char-set "aeiou12345") - (char-set-filter vowel? char-set:ascii (string->char-set "12345"))) - (not (char-set= (string->char-set "aeou12345") - (char-set-filter vowel? char-set:ascii (string->char-set "12345")))) - - (char-set= (string->char-set "aeiou12345") - (char-set-filter! vowel? char-set:ascii (string->char-set "12345"))) - (not (char-set= (string->char-set "aeou12345") - (char-set-filter! vowel? char-set:ascii (string->char-set "12345")))) - - - (char-set= (string->char-set "abcdef12345") - (ucs-range->char-set 97 103 #t (string->char-set "12345"))) - (not (char-set= (string->char-set "abcef12345") - (ucs-range->char-set 97 103 #t (string->char-set "12345")))) - - (char-set= (string->char-set "abcdef12345") - (ucs-range->char-set! 97 103 #t (string->char-set "12345"))) - (not (char-set= (string->char-set "abcef12345") - (ucs-range->char-set! 97 103 #t (string->char-set "12345")))) - - - (char-set= (->char-set #\x) - (->char-set "x") - (->char-set (char-set #\x))) - - (not (char-set= (->char-set #\x) - (->char-set "y") - (->char-set (char-set #\x)))) - - (= 10 (char-set-size (char-set-intersection char-set:ascii char-set:digit))) - - (= 5 (char-set-count vowel? char-set:ascii)) - - (equal? '(#\x) (char-set->list (char-set #\x))) - (not (equal? '(#\X) (char-set->list (char-set #\x)))) - - (equal? "x" (char-set->string (char-set #\x))) - (not (equal? "X" (char-set->string (char-set #\x)))) - - (char-set-contains? (->char-set "xyz") #\x) - (not (char-set-contains? (->char-set "xyz") #\a)) - - (char-set-every char-lower-case? (->char-set "abcd")) - (not (char-set-every char-lower-case? (->char-set "abcD"))) - (char-set-any char-lower-case? (->char-set "abcd")) - (not (char-set-any char-lower-case? (->char-set "ABCD"))) - - (char-set= (->char-set "ABCD") - (let ((cs (->char-set "abcd"))) - (let lp ((cur (char-set-cursor cs)) (ans '())) - (if (end-of-char-set? cur) (list->char-set ans) - (lp (char-set-cursor-next cs cur) - (cons (char-upcase (char-set-ref cs cur)) ans)))))) - - - (char-set= (char-set-adjoin (->char-set "123") #\x #\a) - (->char-set "123xa")) - (not (char-set= (char-set-adjoin (->char-set "123") #\x #\a) - (->char-set "123x"))) - (char-set= (char-set-adjoin! (->char-set "123") #\x #\a) - (->char-set "123xa")) - (not (char-set= (char-set-adjoin! (->char-set "123") #\x #\a) - (->char-set "123x"))) - - (char-set= (char-set-delete (->char-set "123") #\2 #\a #\2) - (->char-set "13")) - (not (char-set= (char-set-delete (->char-set "123") #\2 #\a #\2) - (->char-set "13a"))) - (char-set= (char-set-delete! (->char-set "123") #\2 #\a #\2) - (->char-set "13")) - (not (char-set= (char-set-delete! (->char-set "123") #\2 #\a #\2) - (->char-set "13a"))) - - (char-set= (char-set-intersection char-set:hex-digit (char-set-complement char-set:digit)) - (->char-set "abcdefABCDEF")) - (char-set= (char-set-intersection! (char-set-complement! (->char-set "0123456789")) - char-set:hex-digit) - (->char-set "abcdefABCDEF")) - - (char-set= (char-set-union char-set:hex-digit - (->char-set "abcdefghijkl")) - (->char-set "abcdefABCDEFghijkl0123456789")) - (char-set= (char-set-union! (->char-set "abcdefghijkl") - char-set:hex-digit) - (->char-set "abcdefABCDEFghijkl0123456789")) - - (char-set= (char-set-difference (->char-set "abcdefghijklmn") - char-set:hex-digit) - (->char-set "ghijklmn")) - (char-set= (char-set-difference! (->char-set "abcdefghijklmn") - char-set:hex-digit) - (->char-set "ghijklmn")) - - (char-set= (char-set-xor (->char-set "0123456789") - char-set:hex-digit) - (->char-set "abcdefABCDEF")) - (char-set= (char-set-xor! (->char-set "0123456789") - char-set:hex-digit) - (->char-set "abcdefABCDEF")) - - (call-with-values (lambda () - (char-set-diff+intersection char-set:hex-digit - char-set:letter)) - (lambda (d i) - (and (char-set= d (->char-set "0123456789")) - (char-set= i (->char-set "abcdefABCDEF"))))) - - (call-with-values (lambda () - (char-set-diff+intersection! (char-set-copy char-set:hex-digit) - (char-set-copy char-set:letter))) - (lambda (d i) - (and (char-set= d (->char-set "0123456789")) - (char-set= i (->char-set "abcdefABCDEF")))))))) - -;; ---------------------------------------- - -;; PR 8624 --- make sure there's no error: -(check-true (string? (char-set->string (char-set-complement char-set:graphic)))) From c05db1ecf4663ef94e8a321aa4a951f1b0752e35 Mon Sep 17 00:00:00 2001 From: Jack Firth Date: Thu, 17 Sep 2015 10:30:11 -0700 Subject: [PATCH 244/381] Refactor raco's tool listing code --- racket/collects/raco/all-tools.rkt | 122 +++++++++++++++++------------ 1 file changed, 74 insertions(+), 48 deletions(-) diff --git a/racket/collects/raco/all-tools.rkt b/racket/collects/raco/all-tools.rkt index ebfc09acec..7e71ab0fa1 100644 --- a/racket/collects/raco/all-tools.rkt +++ b/racket/collects/raco/all-tools.rkt @@ -1,58 +1,84 @@ #lang racket/base + (require setup/getinfo racket/list) (provide all-tools) + +(define (log-exn-message-handler exn) + (log-error (exn-message exn)) + #f) + (define (get-info/full/skip dir) - (with-handlers ([exn:fail? (lambda (exn) - (log-error (exn-message exn)) - #f)]) + (with-handlers ([exn:fail? log-exn-message-handler]) (get-info/full dir))) +(define (ensure-list v) + (if (list? v) v (list v))) + +(define (check-tool-not-registered-twice tools entry dir) + (define tool-name (car entry)) + (define previous-tool (hash-ref tools tool-name #f)) + (when previous-tool + (eprintf "warning: tool ~s registered twice: ~e and ~e\n" + tool-name + (car previous-tool) + dir))) + +(define (valid-raco-commands-spec? entry) + (and (list? entry) + (= (length entry) 4) + (string? (car entry)) + (module-path? (cadr entry)) + (string? (caddr entry)) + (or (not (list-ref entry 3)) + (real? (list-ref entry 3))))) + +(define (check-valid-raco-commands-spec entry dir) + (unless (valid-raco-commands-spec? entry) + (eprintf "warning: ~s provided bad `raco-commands' spec: ~e\n" + dir + entry))) + + +(define (get-info-raco-commands full-info-proc) + (ensure-list (full-info-proc 'raco-commands (lambda () null)))) + (define (all-tools) - (let* ([dirs (find-relevant-directories '(raco-commands) 'all-available)] - [tools (make-hash)]) - (for ([i (in-list (filter-map get-info/full/skip dirs))] - [d (in-list dirs)]) - (let ([entries (let ([l (if i - (i 'raco-commands (lambda () null)) - null)]) - (if (list? l) - l - (list l)))]) - (for ([entry (in-list entries)]) - (cond - [(and (list? entry) - (= (length entry) 4) - (string? (car entry)) - (module-path? (cadr entry)) - (string? (caddr entry)) - (or (not (list-ref entry 3)) - (real? (list-ref entry 3)))) - (let ([p (hash-ref tools (car entry) #f)]) - (when p - (eprintf - "warning: tool ~s registered twice: ~e and ~e\n" - (car entry) - (car p) - d))) - (let ([entry (let ([e (cadr entry)]) - (if (or (string? e) - (and (pair? e) - (eq? (car e) 'file) - (relative-path? (cadr e)))) - ;; convert absolute path to realive to "info.rkt": - (list* (car entry) - (build-path d (if (pair? e) - (cadr e) - e)) - (cddr entry)) - ;; module path is absolute already: - entry))]) - (hash-set! tools (car entry) entry))] - [else - (eprintf "warning: ~s provided bad `raco-commands' spec: ~e\n" - d - entry)])))) - tools)) + (define tools (make-hash)) + (define dirs (find-relevant-directories '(raco-commands) 'all-available)) + (define infos (filter-map get-info/full/skip dirs)) + (for ([i (in-list infos)] + [d (in-list dirs)]) + (define entries (get-info-raco-commands i)) + (for ([entry (in-list entries)]) + (check-valid-raco-commands-spec entry d) + (check-tool-not-registered-twice tools entry d) + (add-tool! tools (convert-entry entry d)))) + tools) + +(define (convert-entry tool-entry dir) + (define tool-mod-path (cadr tool-entry)) + (if (non-module-tool-path? tool-mod-path) + (convert-module-tool-path tool-entry tool-mod-path dir) + tool-entry)) ;; module path is absolute already: + +(define (non-module-tool-path? tool-mod-path) + (or (string? tool-mod-path) + (and (pair? tool-mod-path) + (eq? (car tool-mod-path) 'file) + (relative-path? (cadr tool-mod-path))))) + +;; convert absolute path to relative to "info.rkt": +(define (convert-module-tool-path tool-entry tool-mod-path dir) + (define new-path + (build-path dir (if (pair? tool-mod-path) + (cadr tool-mod-path) + tool-mod-path))) + (list* (car tool-entry) + new-path + (cddr tool-entry))) + +(define (add-tool! tools tool-entry) + (hash-set! tools (car tool-entry) tool-entry)) From d305ceffe1e3b6df3a7a244c2a0a43aaa6e0d21c Mon Sep 17 00:00:00 2001 From: Jack Firth Date: Thu, 17 Sep 2015 11:14:04 -0700 Subject: [PATCH 245/381] Refactor command-name --- racket/collects/raco/command-name.rkt | 37 ++++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/racket/collects/raco/command-name.rkt b/racket/collects/raco/command-name.rkt index 5cbe917428..754d3a6b34 100644 --- a/racket/collects/raco/command-name.rkt +++ b/racket/collects/raco/command-name.rkt @@ -10,24 +10,25 @@ (define-values (program+command-name) (lambda () - (let-values ([(p) (find-system-path 'run-file)] - [(n) (current-command-name)]) - (if n - (format "~a ~a" p n) - p)))) - + (define-values (p) (find-system-path 'run-file)) + (define-values (n) (current-command-name)) + (if n (format "~a ~a" p n) p))) + (define-values (short-program+command-name) (lambda () - (let-values ([(p) (find-system-path 'run-file)] - [(n) (current-command-name)]) - (let-values ([(base name dir?) (split-path p)]) - (let-values ([(name) (if (eq? (system-type) 'windows) - (string->path-element - (regexp-replace #rx"(?i:[.]exe)$" - (path-element->string name) - "")) - name)]) - (if n - (format "~a ~a" name n) - (path->string name)))))))) + (define-values (p) (find-system-path 'run-file)) + (define-values (n) (current-command-name)) + (define-values (base name dir?) (split-path p)) + (define-values (converted-name) (convert-name name)) + (if n + (format "~a ~a" converted-name n) + (path->string converted-name)))) + (define-values (convert-name) + (lambda (name) + (if (eq? (system-type) 'windows) + (string->path-element + (regexp-replace #rx"(?i:[.]exe)$" + (path-element->string name) + "")) + name)))) From 38661481ede6237526832a4434e59a79900997fb Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Tue, 15 Sep 2015 23:12:59 +0200 Subject: [PATCH 246/381] Missing ')' in bool.c Found by cppcheck. --- racket/src/racket/src/bool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/bool.c b/racket/src/racket/src/bool.c index 9781955772..5f0d5d4288 100644 --- a/racket/src/racket/src/bool.c +++ b/racket/src/racket/src/bool.c @@ -220,8 +220,8 @@ XFORM_NONGCING static MZ_INLINE int mz_long_double_eqv(long_double a, long_doubl if (MZ_IS_LONG_NAN(b)) return 0; else { - if (long_double_eqv(a, get_long_double_zero()) { - if (long_double_eqv(b, get_long_double_zero()) { + if (long_double_eqv(a, get_long_double_zero())) { + if (long_double_eqv(b, get_long_double_zero())) { return scheme_long_minus_zero_p(a) == scheme_long_minus_zero_p(b); } } From b7bcd4f6872067771612c987f56766478a437aae Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Tue, 15 Sep 2015 23:17:46 +0200 Subject: [PATCH 247/381] Remove extra ')'. Found by cppcheck. --- racket/src/racket/src/port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 6645310f9f..8d5ee727f8 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -10288,7 +10288,7 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[]) scheme_contract_error(name, "non-#f port argument not allowed on this platform", "port", 1, args[i], - NULL)); + NULL); } if (c > 4) { From 0b9cda5018bbbd0302814197066f0039fd6b4452 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Sep 2015 09:25:26 -0600 Subject: [PATCH 248/381] avoid undefined behavior in hashing inexacts Casting a negative floating-point number to an unsigned integer is not ok. Corece to a signed integer, first. Thanks to John Regehr for help. --- racket/src/racket/src/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index 2a846d72bb..7013f3da7c 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -1117,7 +1117,7 @@ XFORM_NONGCING static uintptr_t dbl_hash_val(double d) d = frexp(d, &e); } - return ((uintptr_t)(d * (1 << 30))) + e; + return ((uintptr_t)(intptr_t)(d * (1 << 30))) + (uintptr_t)e; } XFORM_NONGCING static uintptr_t dbl_hash2_val(double d) From 4abedf63e87421dc48f10f8ba25158fbf9d1e372 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Sep 2015 11:47:15 -0600 Subject: [PATCH 249/381] raco setup: don't try to "sync" a doc that isn't pre-rendered On my machine, the sync path was sometimes triggered for "htdp-ptr". (I'm not sure why; progress toward determinsitic bytecode might be relevant.) Adjust the trigger for sync mode to check that the needed "provides.sxref" file exists. --- pkgs/racket-index/setup/scribble.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-index/setup/scribble.rkt b/pkgs/racket-index/setup/scribble.rkt index 82cccdf238..e27f085c50 100644 --- a/pkgs/racket-index/setup/scribble.rkt +++ b/pkgs/racket-index/setup/scribble.rkt @@ -1062,7 +1062,10 @@ (and can-run? (not (equal? (car stamp-data) src-sha1)) - 'newer)))] + 'newer) + (and (or (not provides-time) + (provides-time . < . info-out-time)) + (not (file-exists? (build-path (doc-dest-dir doc) "provides.sxref"))))))] [up-to-date? (not out-of-date)] [can-run? (and src-zo (or (not latex-dest) From 40f9467c072eb09d23ee38a4af6009c1ee3e3709 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Sep 2015 12:26:32 -0600 Subject: [PATCH 250/381] count phantom bytes as regular allocation The original idea was to count phantom bytes as "administrative overhead", but issues discussed in #962 identified problems with that idea. Finish shifting the accounting to treat phantom bytes as payload allocation. --- racket/src/racket/gc2/newgc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index b4afb84306..5e936c0ec5 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5027,8 +5027,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin int next_gc_full; - old_mem_use = gc->memory_in_use; - old_gen0 = gc->gen0.current_size; + old_mem_use = gc->memory_in_use; /* includes gc->phantom_count */ + old_gen0 = gc->gen0.current_size + gc->gen0_phantom_count; old_mem_allocated = mmu_memory_allocated(gc->mmu) + gc->phantom_count + gc->gen0_phantom_count; TIME_DECLS(); @@ -5272,8 +5272,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin lmi->full = gc->gc_full, lmi->pre_used = old_mem_use + old_gen0; lmi->post_used = gc->memory_in_use; - lmi->pre_admin = old_mem_allocated+gc->phantom_count; - lmi->post_admin = mmu_memory_allocated(gc->mmu); + lmi->pre_admin = old_mem_allocated; + lmi->post_admin = mmu_memory_allocated(gc->mmu)+gc->phantom_count; } GC_propagate_hierarchy_memory_use(); #endif From a9015e5484865157f379ded2adef3bf3be030532 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Sep 2015 12:40:14 -0600 Subject: [PATCH 251/381] GC: remove unmaintained counters --- racket/src/racket/gc2/block_cache.c | 6 -- racket/src/racket/gc2/newgc.c | 89 ----------------------------- racket/src/racket/gc2/page_range.c | 3 - racket/src/racket/gc2/weak.c | 1 - 4 files changed, 99 deletions(-) diff --git a/racket/src/racket/gc2/block_cache.c b/racket/src/racket/gc2/block_cache.c index f9f399a766..0de6e63b5d 100644 --- a/racket/src/racket/gc2/block_cache.c +++ b/racket/src/racket/gc2/block_cache.c @@ -224,7 +224,6 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect BD_MAP_UNSET_BIT(bd->protect_map, end_pos); end_pos++; } - GC_MP_CNT_INC(mp_alloc_med_big_cnt); os_protect_pages((char *)p - ((pos - start_pos) * APAGE_SIZE), (end_pos - start_pos) * APAGE_SIZE, 1); @@ -416,11 +415,6 @@ static ssize_t block_cache_flush_freed_pages(BlockCache* bc) { } alloc_cache_size_diff = alloc_cache_flush_freed_pages(bc->bigBlockCache); -#ifdef GC_MP_CNT - mp_bc_freed = -size_diff; - mp_ac_freed = -alloc_cache_size_diff; -#endif - return size_diff + alloc_cache_size_diff; } diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 5e936c0ec5..f4cf9b0d72 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -11,27 +11,6 @@ generation eventually compacts. */ -/* #define GC_MP_CNT */ -/* GC MProtect Counters */ -#ifdef GC_MP_CNT -int mp_write_barrier_cnt; -int mp_mark_cnt; -int mp_alloc_med_big_cnt; -int mp_pr_add_cnt; -int mp_pr_call_cnt; -int mp_pr_ff_cnt; -int mp_gc_unprotect_cnt; -int mp_gc_protect_cnt; -int mp_gcs_cnt; -intptr_t mp_prev_compact_cnt; -intptr_t mp_compact_cnt; -intptr_t mp_bc_freed; -intptr_t mp_ac_freed; -# define GC_MP_CNT_INC(x) ((x)++) -#else -# define GC_MP_CNT_INC(x) /* empty */ -#endif - #if 0 # define POINTER_OWNERSHIP_CHECK #endif @@ -2807,7 +2786,6 @@ static int designate_modified_gc(NewGC *gc, void *p) if (page) { page->mprotected = 0; mmu_write_unprotect_page(gc->mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); - GC_MP_CNT_INC(mp_write_barrier_cnt); if (!page->back_pointers) set_has_back_pointers(gc, page); gc->modified_unprotects++; @@ -3631,7 +3609,6 @@ void GC_mark2(void *pp, struct NewGC *gc) if (work->mprotected) { work->mprotected = 0; mmu_write_unprotect_page(gc->mmu, work->addr, APAGE_SIZE, page_mmu_type(work), &work->mmu_src_block); - GC_MP_CNT_INC(mp_mark_cnt); } newplace = PTR(NUM(work->addr) + work->size); } else { @@ -4172,9 +4149,6 @@ static void reset_gen1_pages_live_and_previous_sizes(NewGC *gc) { mpage *work; int i; -#ifdef GC_MP_CNT - mp_gc_unprotect_cnt = mp_pr_add_cnt; -#endif GCDEBUG((DEBUGOUTF, "MAJOR COLLECTION - PREPPING PAGES - reset live_size, reset previous_size, unprotect.\n")); /* we need to make sure that previous_size for every page is reset, so @@ -4199,9 +4173,6 @@ static void reset_gen1_pages_live_and_previous_sizes(NewGC *gc) } mmu_flush_write_unprotect_ranges(gc->mmu); -#ifdef GC_MP_CNT - mp_gc_unprotect_cnt = mp_pr_add_cnt - mp_gc_unprotect_cnt; -#endif } static void mark_backpointers(NewGC *gc) @@ -4334,9 +4305,6 @@ inline static void do_heap_compact(NewGC *gc) int tic_tock = gc->num_major_collects % 2; mmu_prep_for_compaction(gc->mmu); -#ifdef GC_MP_CNT - mp_prev_compact_cnt = mp_compact_cnt; -#endif for(i = 0; i < PAGE_BIG; i++) { mpage *work = gc->gen1_pages[i], *prev, *npage; @@ -4392,9 +4360,6 @@ inline static void do_heap_compact(NewGC *gc) fprintf(gcdebugOUT(gc), "Compacting from %p to %p \n", start+1, newplace+1); fprintf_debug(gc, work, "Compacting", info, gcdebugOUT(gc), 0); } -#endif -#ifdef GC_MP_CNT - mp_compact_cnt += gcWORDS_TO_BYTES(info->size); #endif GCDEBUG((DEBUGOUTF,"Moving size %i object from %p to %p\n", gcWORDS_TO_BYTES(info->size), start+1, newplace+1)); @@ -4899,9 +4864,6 @@ static void protect_old_pages(NewGC *gc) MMU *mmu = gc->mmu; mpage *page; int i; -#ifdef GC_MP_CNT - mp_gc_protect_cnt = mp_pr_add_cnt; -#endif for (i = 0; i < PAGE_TYPES; i++) { if (i != PAGE_ATOMIC) { @@ -4928,55 +4890,8 @@ static void protect_old_pages(NewGC *gc) } mmu_flush_write_protect_ranges(mmu); - -#ifdef GC_MP_CNT - mp_gc_protect_cnt = mp_pr_add_cnt - mp_gc_protect_cnt; -#endif } -#ifdef GC_MP_CNT -void print_debug_stats(NewGC *gc) { - char* color; - if (!(mp_gcs_cnt % 30)) { - printf("GCINSTANC WRITE_BA GC_MARK2 DURINGGC PR_ADD__ PR_PROT_ PR_FFLUS UNPROTEC REPROTEC MMUALLOCATED COMPACTED_ COMPACTLOC BC_FREED AC_FREED\n"); - } - mp_gc_protect_cnt = mp_pr_add_cnt - mp_gc_protect_cnt; - mp_gcs_cnt ++; - - if (gc->gc_full) { - if (gc == MASTERGC) { - if (gc->num_major_collects % 2) color = "\033[0;32m"; - else color = "\033[1;32m"; - } - else { - if (gc->num_major_collects % 2) color = "\033[0;31m"; - else color = "\033[1;31m"; - } - } - else - color = "\033\[0;37m"; - printf("%s%p %08i %08i %08i %08i %08i %08i %08i %08i %012li %010li %010li %08li %08li%s\n", - color, - gc, - mp_write_barrier_cnt, - mp_mark_cnt, - mp_alloc_med_big_cnt, - mp_pr_add_cnt, - mp_pr_call_cnt, - mp_pr_ff_cnt, - mp_gc_unprotect_cnt, - mp_gc_protect_cnt, - mmu_memory_allocated(gc->mmu), - mp_compact_cnt, - mp_compact_cnt - mp_prev_compact_cnt, - mp_bc_freed, - mp_ac_freed, - "\033\[0;37m"); - mp_bc_freed = 0; - mp_ac_freed = 0; -} -#endif - static void park_for_inform_callback(NewGC *gc) { /* Avoid nested collections, which would need @@ -5220,10 +5135,6 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin mmu_flush_freed_pages(gc->mmu); reset_finalizer_tree(gc); -#ifdef GC_MP_CNT - print_debug_stats(gc); -#endif - TIME_STEP("reset"); /* now we do want the allocator freaking if we go over half */ diff --git a/racket/src/racket/gc2/page_range.c b/racket/src/racket/gc2/page_range.c index a4e71c7d58..4795f23703 100644 --- a/racket/src/racket/gc2/page_range.c +++ b/racket/src/racket/gc2/page_range.c @@ -45,9 +45,7 @@ static void page_range_free(Page_Range *pr) static void page_range_add(Page_Range *pr, void *_start, uintptr_t len, int writeable) { - GC_MP_CNT_INC(mp_pr_add_cnt); if (!page_range_add_worker(pr, _start, len)) { - GC_MP_CNT_INC(mp_pr_ff_cnt); page_range_flush(pr, writeable); page_range_add_worker(pr, _start, len); } @@ -62,7 +60,6 @@ static void page_range_flush(Page_Range *pr, int writeable) for (work = pr->range_start; work; work = work->next) { os_protect_pages((void *)work->start, work->len, writeable); - GC_MP_CNT_INC(mp_pr_call_cnt); } page_range_reset(pr); diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index 502f878b8e..3964715b4a 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -218,7 +218,6 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) if (page->mprotected) { page->mprotected = 0; mmu_write_unprotect_page(gc->mmu, page->addr, APAGE_SIZE, page_mmu_type(page), &page->mmu_src_block); - GC_MP_CNT_INC(mp_mark_cnt); } p = (void **)GC_resolve2(wb->secondary_erase, gc); From 1a48418844fc34ea7c2cc5d64d874a3507ea2c22 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Sep 2015 18:55:22 -0600 Subject: [PATCH 252/381] infrastructure for `raco ctool --c-mods --runtime

` Make the runtime-file gatherer, which is normally used by `raco exec`, work also for modules prepared for an executable that embeds Racket. --- .../scribblings/inside/embedding.scrbl | 10 +++ .../racket-doc/scribblings/inside/hooks.scrbl | 7 ++ pkgs/racket-doc/scribblings/raco/c-mods.scrbl | 12 ++- .../scribblings/raco/dist-api.scrbl | 22 ++++-- racket/collects/compiler/distribute.rkt | 77 +++++++++++-------- 5 files changed, 91 insertions(+), 37 deletions(-) diff --git a/pkgs/racket-doc/scribblings/inside/embedding.scrbl b/pkgs/racket-doc/scribblings/inside/embedding.scrbl index fdb491a4f7..2064ca5831 100644 --- a/pkgs/racket-doc/scribblings/inside/embedding.scrbl +++ b/pkgs/racket-doc/scribblings/inside/embedding.scrbl @@ -200,6 +200,16 @@ int main(int argc, char *argv[]) } } +If modules embedded in the executable need to access runtime files +(via @racketmodname[racket/runtime-path] forms), supply the +@DFlag{runtime} flag to @exec{raco ctool}, specifying a directory +where the runtime files are to be gathered. The modules in the +generated @filepath{.c} file will then refer to the files in that +directory; the directory is normally specified relative to the +executable, but the embedding application must call +@cppi{scheme_set_exec_cmd} to set the executable path (typically +@cpp{argv[0]}) before declaring modules. + On Mac OS X, or on Windows when Racket is compiled to a DLL using Cygwin, the garbage collector cannot find static variables automatically. In that case, @cppi{scheme_main_setup} must be called with a diff --git a/pkgs/racket-doc/scribblings/inside/hooks.scrbl b/pkgs/racket-doc/scribblings/inside/hooks.scrbl index 73a86931fd..eb6a5ec9c3 100644 --- a/pkgs/racket-doc/scribblings/inside/hooks.scrbl +++ b/pkgs/racket-doc/scribblings/inside/hooks.scrbl @@ -64,6 +64,13 @@ Sets the path to be returned by @racket[(find-system-path 'addon-dir)].} +@function[(void scheme_set_exec_cmd + [const-char* path])]{ + +Sets the path to be returned by @racket[(find-system-path +'exec-file)].} + + @function[(void scheme_init_collection_paths_post [Scheme_Env* env] [Scheme_Object* pre_extra_paths] diff --git a/pkgs/racket-doc/scribblings/raco/c-mods.scrbl b/pkgs/racket-doc/scribblings/raco/c-mods.scrbl index 58761a3d06..a6ef24eee2 100644 --- a/pkgs/racket-doc/scribblings/raco/c-mods.scrbl +++ b/pkgs/racket-doc/scribblings/raco/c-mods.scrbl @@ -1,5 +1,7 @@ #lang scribble/doc -@(require scribble/manual "common.rkt") +@(require scribble/manual + "common.rkt" + scribble/bnf) @title[#:tag "c-mods"]{Embedding Modules via C} @@ -14,3 +16,11 @@ a @tt{declare_modules} function that puts the module declarations into a namespace. Thus, using the output of @exec{raco ctool --c-mods}, a program can embed Racket with a set of modules so that it does not need a @filepath{collects} directory to load modules at run time. + +If the embedded modules refer to runtime files, the files can be +gathers by supplying the @DFlag{runtime} argument to @exec{raco ctool +--cmods}, specifying a directory @nonterm{dir} to hold the files. +Normally, @nonterm{dir} is a relative path, and files are found at run +time in @nonterm{dir} relative to the executable, but a separate path +(usually relative) for run time can be specified with +@DFlag{runtime-access}. diff --git a/pkgs/racket-doc/scribblings/raco/dist-api.scrbl b/pkgs/racket-doc/scribblings/raco/dist-api.scrbl index 25d8fc1727..a650feb02b 100644 --- a/pkgs/racket-doc/scribblings/raco/dist-api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/dist-api.scrbl @@ -16,17 +16,26 @@ perform the same work as @exec{raco distribute}.} @defproc[(assemble-distribution [dest-dir path-string?] [exec-files (listof path-string?)] + [#:executables? executables? any/c #t] + [#:relative-base relative-base (or/c path-string? #f) #f] [#:collects-path path (or/c false/c (and/c path-string? relative-path?)) #f] [#:copy-collects dirs (listof path-string?) null]) void?]{ Copies the executables in @racket[exec-files] to the directory -@racket[dest-dir], along with DLLs, frameworks, and/or shared -libraries that the executables need to run a different machine. +@racket[dest-dir], along with DLLs, frameworks, shared libraries, +and/or runtime files that the executables need to run a different +machine. If @racket[executables?] is @racket[#f], then the +@racket[exec-files] are treated as plain data files, instead of +executables, and they are modified in-place. The arrangement of the executables and support files in -@racket[dest-dir] depends on the platform. In general -@racket[assemble-distribution] tries to do the Right Thing. +@racket[dest-dir] depends on the platform. In general, +@racket[assemble-distribution] tries to do the Right Thing, but a +non-@racket[#f] value for @racket[relative-base] specifies a +path for reaching the assembled content relative to the executable at +run time. When @racket[executables?] is @racket[#f], then the default +access path is @racket[dest-dir], with its relativeness preserved. If a @racket[#:collects-path] argument is given, it overrides the default location of the main @filepath{collects} directory for the @@ -35,4 +44,7 @@ directory (typically inside it). The content of each directory in the @racket[#:copy-collects] argument is copied into the main @filepath{collects} directory for the packaged -executables.} +executables. + +@history[#:changed "6.2.900.17" @elem{Added the @racket[#:executables?] + and @racket[#:relative-base] arguments.}]} diff --git a/racket/collects/compiler/distribute.rkt b/racket/collects/compiler/distribute.rkt index ca6d6291af..c235a144d4 100644 --- a/racket/collects/compiler/distribute.rkt +++ b/racket/collects/compiler/distribute.rkt @@ -17,42 +17,50 @@ (define (assemble-distribution dest-dir orig-binaries + #:executables? [executables? #t] + #:relative-base [relative-base #f] #:collects-path [collects-path #f] ; relative to dest-dir #:copy-collects [copy-collects null]) - (let* ([types (map get-binary-type orig-binaries)] + (let* ([types (if executables? + (map get-binary-type orig-binaries) + (map (lambda (v) #f) orig-binaries))] [_ (unless (directory-exists? dest-dir) (make-directory dest-dir))] [sub-dirs (map (lambda (b type) - (case (cross-system-type) - [(windows) #f] - [(unix) "bin"] - [(macosx) (if (memq type '(gracketcgc gracket3m)) - #f - "bin")])) - orig-binaries + (and type + (case (cross-system-type) + [(windows) #f] + [(unix) "bin"] + [(macosx) (if (memq type '(gracketcgc gracket3m)) + #f + "bin")]))) + orig-binaries types)] ;; Copy binaries into place: [binaries (map (lambda (b sub-dir type) - (let ([dest-dir (if sub-dir - (build-path dest-dir sub-dir) - dest-dir)]) - (unless (directory-exists? dest-dir) - (make-directory dest-dir)) - (let-values ([(base name dir?) (split-path b)]) - (let ([dest (build-path dest-dir name)]) - (if (and (memq type '(gracketcgc gracket3m)) - (eq? 'macosx (cross-system-type))) - (begin - (copy-app b dest) - (app-to-file dest)) - (begin - (copy-file* b dest) - dest)))))) + (if type + (let ([dest-dir (if sub-dir + (build-path dest-dir sub-dir) + dest-dir)]) + (unless (directory-exists? dest-dir) + (make-directory dest-dir)) + (let-values ([(base name dir?) (split-path b)]) + (let ([dest (build-path dest-dir name)]) + (if (and (memq type '(gracketcgc gracket3m)) + (eq? 'macosx (cross-system-type))) + (begin + (copy-app b dest) + (app-to-file dest)) + (begin + (copy-file* b dest) + dest))))) + b)) orig-binaries sub-dirs types)] - [single-mac-app? (and (eq? 'macosx (cross-system-type)) + [single-mac-app? (and executables? + (eq? 'macosx (cross-system-type)) (= 1 (length types)) (memq (car types) '(gracketcgc gracket3m)))]) ;; Create directories for libs, collects, and extensions: @@ -78,7 +86,8 @@ (let* ([specific-lib-dir (build-path "lib" "plt" - (if (null? binaries) + (if (or (not executables?) + (null? binaries)) "generic" (let-values ([(base name dir?) (split-path (car binaries))]) @@ -96,7 +105,8 @@ (make-directory* collects-dir) (make-directory* exts-dir) ;; Copy libs into place - (install-libs lib-dir types) + (when executables? + (install-libs lib-dir types)) ;; Copy collections into place (for-each (lambda (dir) (for-each (lambda (f) @@ -106,10 +116,14 @@ (directory-list dir))) copy-collects) ;; Patch binaries to find libs - (patch-binaries binaries types) + (when executables? + (patch-binaries binaries types)) (let ([relative->binary-relative (lambda (sub-dir type relative-dir) (cond + [relative-base relative-base] + [(not executables?) + (build-path dest-dir relative-dir)] [sub-dir (build-path 'up relative-dir)] [(and (eq? 'macosx (cross-system-type)) @@ -120,10 +134,11 @@ relative-dir]))]) ;; Patch binaries to find collects (for-each (lambda (b type sub-dir) - (set-collects-path - b - (collects-path->bytes - (relative->binary-relative sub-dir type relative-collects-dir)))) + (when type + (set-collects-path + b + (collects-path->bytes + (relative->binary-relative sub-dir type relative-collects-dir))))) binaries types sub-dirs) (unless (null? binaries) ;; Copy over extensions and adjust embedded paths: From a88d52bd348199871eb6885276aca949d3328dbe Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Sep 2015 19:19:29 -0600 Subject: [PATCH 253/381] configure: make `--enable-libs` on by default --- racket/src/configure | 15 +++++++++------ racket/src/racket/Makefile.in | 3 +++ racket/src/racket/configure.ac | 6 +++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/racket/src/configure b/racket/src/configure index af9550f030..96711f02cf 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -803,6 +803,7 @@ enable_natipkg enable_shared enable_dynlib enable_lt +enable_libs enable_libffi enable_sdk enable_xonx @@ -1449,7 +1450,7 @@ Optional Features: --enable-shared create shared libraries (ok, but not recommended) --enable-dynlib same as --enable-shared --enable-lt= use instead of libtool; disable to use bundled - --enable-libs install Racket static libraries, if any + --enable-libs install static libraries, if any (enabled by default) --enable-libffi use installed libffi (enabled by default for Unix) --enable-sdk= use Mac OS X 10.4 SDK directory --enable-sdk5= use Mac OS X 10.5 SDK directory @@ -1462,7 +1463,7 @@ Optional Features: --enable-macprefix allow --prefix with a Mac OS X install --enable-mac64 allow 64-bit Mac OS X build (enabled by default) --enable-cgcdefault use CGC as default build (NOT RECOMMENDED) - --enable-sgc use Senora GC instead of the Boehm GC (enabled by default) + --enable-sgc use Senora GC instead of Boehm GC (enabled by default) --enable-sgcdebug use Senora GC for debugging (expensive debug mode) --enable-backtrace 3m: support GC backtrace dumps (expensive debug mode) --enable-pthread link with pthreads (usually auto-enabled if needed) @@ -2680,9 +2681,11 @@ else enable_lt=default fi -# Check whether --enable-dynlib was given. -if test "${enable_dynlib+set}" = set; then : - enableval=$enable_dynlib; +# Check whether --enable-libs was given. +if test "${enable_libs+set}" = set; then : + enableval=$enable_libs; +else + enable_libs=yes fi @@ -3050,7 +3053,7 @@ show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping" -show_explicitly_enabled "${enable_libs}" "Installation of static libraries (if any)" +show_explicitly_disabled "${enable_libs}" "Installation of static libraries (if any)" show_explicitly_disabled "${enable_mac64}" "64-bit Mac OS X" diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 91bb9d6645..3055055387 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -406,6 +406,8 @@ unix-install-cgc: unix-install-libs-cgc: cd ..; $(ICP) racket/libmzgc.@LIBSFX@ "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" cd ..; $(ICP) racket/libracket.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" unix-no-install-libs-cgc: $(NOOP) @@ -422,6 +424,7 @@ unix-install-3m: unix-install-libs-3m: cd ..; $(ICP) racket/libracket3m.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" + cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" unix-no-install-libs-3m: $(NOOP) diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 1675db1ff7..a6f7b73b3d 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -53,7 +53,7 @@ AC_ARG_ENABLE(natipkg, [ --enable-natipkg add "-natipkg" to library subp AC_ARG_ENABLE(shared, [ --enable-shared create shared libraries (ok, but not recommended)]) AC_ARG_ENABLE(dynlib, [ --enable-dynlib same as --enable-shared]) AC_ARG_ENABLE(lt, [ --enable-lt= use instead of libtool; disable to use bundled], LIBTOOLPROG="$enableval", enable_lt=default) -AC_ARG_ENABLE(dynlib, [ --enable-libs install Racket static libraries, if any]) +AC_ARG_ENABLE(libs, [ --enable-libs install static libraries, if any (enabled by default)], , enable_libs=yes) AC_ARG_ENABLE(libffi, [ --enable-libffi use installed libffi (enabled by default for Unix)], , enable_libffi=default) @@ -69,7 +69,7 @@ AC_ARG_ENABLE(macprefix, [ --enable-macprefix allow --prefix with a Mac OS AC_ARG_ENABLE(mac64, [ --enable-mac64 allow 64-bit Mac OS X build (enabled by default)], , enable_mac64=yes) AC_ARG_ENABLE(cgcdefault, [ --enable-cgcdefault use CGC as default build (NOT RECOMMENDED)]) -AC_ARG_ENABLE(sgc, [ --enable-sgc use Senora GC instead of the Boehm GC (enabled by default)], , enable_sgc=yes) +AC_ARG_ENABLE(sgc, [ --enable-sgc use Senora GC instead of Boehm GC (enabled by default)], , enable_sgc=yes) AC_ARG_ENABLE(sgcdebug,[ --enable-sgcdebug use Senora GC for debugging (expensive debug mode)]) AC_ARG_ENABLE(backtrace, [ --enable-backtrace 3m: support GC backtrace dumps (expensive debug mode)]) @@ -325,7 +325,7 @@ show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping" -show_explicitly_enabled "${enable_libs}" "Installation of static libraries (if any)" +show_explicitly_disabled "${enable_libs}" "Installation of static libraries (if any)" show_explicitly_disabled "${enable_mac64}" "64-bit Mac OS X" From fccd86d67d69f362653a7f9c07855ed607b83a0f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Sep 2015 21:40:39 -0600 Subject: [PATCH 254/381] configure: `--enable-racket=auto` to simplify cross-compilation Using `--enable-racket=auto` causes a Racket for the current platform to be built in a "local" subdirectory of the build directory as support for cross-compilation. --- racket/src/Makefile.in | 15 +++++++++++++++ racket/src/README | 13 +++++++++---- racket/src/configure | 18 ++++++++++++++++-- racket/src/racket/configure.ac | 17 +++++++++++++++-- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/racket/src/Makefile.in b/racket/src/Makefile.in index 51e0b4660b..e15d1367b9 100644 --- a/racket/src/Makefile.in +++ b/racket/src/Makefile.in @@ -54,6 +54,7 @@ TAGS: etags `find "@srcdir@/racket" -type f` 3m: + $(MAKE) @MAKE_LOCAL_RACKET@ cd racket; $(MAKE) 3m $(MAKE) @MAKE_GRACKET@-3m @@ -64,6 +65,7 @@ no-3m: $(NOOP) cgc: + $(MAKE) @MAKE_LOCAL_RACKET@ cd racket; $(MAKE) cgc $(MAKE) @MAKE_GRACKET@-cgc @@ -77,6 +79,19 @@ both: $(MAKE) cgc $(MAKE) 3m +# Cross-compilation helper: + +no-local-racket: + $(NOOP) + +local/racket/racket3m: + mkdir -p local + $(MAKE) local/Makefile + cd local ; $(MAKE) + +local/Makefile: + cd local ; `cd ..; cd $(srcdir); pwd`/configure --disable-gracket + # Install (common) ---------------------------------------- INST_CONFIG = -X @DIRCVTPRE@"$(DESTDIR)$(collectsdir)"@DIRCVTPOST@ -G @DIRCVTPRE@"$(DESTDIR)$(configdir)"@DIRCVTPOST@ diff --git a/racket/src/README b/racket/src/README index d7920f0e77..46265f9e47 100644 --- a/racket/src/README +++ b/racket/src/README @@ -271,11 +271,16 @@ Cross-compilation requires at least two flags to `configure': such as `OS-gcc' and `OS-strip'. * `--enable-racket=RACKET', where RACKET is a path to a Racket - executable for the version being compiled that runs on the build - platform. + executable that runs on the build platform; the executable must be + the same version of Racket as being built for the target platform. This flag is needed because building and installing Racket requires - running (an intermediate version of) Racket. + running (an existing build of) Racket. + + Use "auto" for RACKET to indicates that one should be built + automatically for the current platform. In that case, `make` + will run `configure` again (with no arguments) in a "local" + subdirectory to create a build for the current platform. Some less commonly needed `configure' flags: @@ -292,7 +297,7 @@ the NDK, use (all on one line) configure --host=arm-linux-androideabi --enable-sysroot="[ndk]/platforms/android-[N]/arch-arm" - --enable-racket=racket + --enable-racket=auto where [ndk] is the path to the installed NDK, [N] is a target version of Android (such as 14), and diff --git a/racket/src/configure b/racket/src/configure index 96711f02cf..84167ff948 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -624,6 +624,7 @@ enable_option_checking=no ac_subst_vars='LTLIBOBJS LIBOBJS subdirs +MAKE_LOCAL_RACKET CGC_IF_NEEDED_FOR_MMM RUN_RACKET_MAIN_VARIANT RUN_RACKET_MMM @@ -1441,7 +1442,7 @@ Optional Features: --enable-float support single-precision floats (enabled by default) --enable-floatinstead use single-precision by default (NOT RECOMMENDED) --enable-extflonum support extflonums (enabled by default, if available) - --enable-racket= use as Racket executable to build Racket + --enable-racket= use as Racket to build; or "auto" to create --enable-origtree install with original directory structure --enable-pkgscope= set `raco pkg' default: installation, user, or shared --enable-docs build docs on install (enabled by default) @@ -3096,7 +3097,11 @@ if test "${enable_sysroot}" != "" ; then fi if test "${enable_racket}" != "" ; then - echo "=== Using Racket executable ${enable_racket}" + if test "${enable_racket}" == "auto" ; then + echo "=== Creating and using local Racket executable" + else + echo "=== Using Racket executable ${enable_racket}" + fi fi INSTALL_PKGSCOPE=user @@ -3180,6 +3185,8 @@ use_flag_posix_pthread=no skip_iconv_check=no check_page_size=yes +MAKE_LOCAL_RACKET=no-local-racket + ###### OSKit stuff ####### if test "${enable_oskit}" = "yes" ; then @@ -6646,6 +6653,11 @@ fi ############## Racket for Racket ################ +if test "${enable_racket}" = "auto" ; then + enable_racket="`pwd`/local/racket/racket3m" + MAKE_LOCAL_RACKET="local/racket/racket3m" +fi + if test "${enable_racket}" = "" ; then RUN_RACKET_CGC='$(RUN_THIS_RACKET_CGC)' RUN_RACKET_MMM='$(RUN_THIS_RACKET_MMM)' @@ -6852,6 +6864,8 @@ LIBS="$LIBS $EXTRALIBS" + + diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index a6f7b73b3d..41e2e7aff9 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -41,7 +41,7 @@ AC_ARG_ENABLE(float, [ --enable-float support single-precision float AC_ARG_ENABLE(floatinstead, [ --enable-floatinstead use single-precision by default (NOT RECOMMENDED)]) AC_ARG_ENABLE(extflonum, [ --enable-extflonum support extflonums (enabled by default, if available)], , enable_extflonum=default) -AC_ARG_ENABLE(racket, [ --enable-racket= use as Racket executable to build Racket]) +AC_ARG_ENABLE(racket, [ --enable-racket= use as Racket to build; or "auto" to create]) AC_ARG_ENABLE(origtree,[ --enable-origtree install with original directory structure]) AC_ARG_ENABLE(pkgscope,[ --enable-pkgscope= set `raco pkg' default: installation, user, or shared]) @@ -368,7 +368,11 @@ if test "${enable_sysroot}" != "" ; then fi if test "${enable_racket}" != "" ; then - echo "=== Using Racket executable ${enable_racket}" + if test "${enable_racket}" == "auto" ; then + echo "=== Creating and using local Racket executable" + else + echo "=== Using Racket executable ${enable_racket}" + fi fi INSTALL_PKGSCOPE=user @@ -452,6 +456,8 @@ use_flag_posix_pthread=no skip_iconv_check=no check_page_size=yes +MAKE_LOCAL_RACKET=no-local-racket + ###### OSKit stuff ####### if test "${enable_oskit}" = "yes" ; then @@ -1561,6 +1567,11 @@ fi ############## Racket for Racket ################ +if test "${enable_racket}" = "auto" ; then + enable_racket="`pwd`/local/racket/racket3m" + MAKE_LOCAL_RACKET="local/racket/racket3m" +fi + if test "${enable_racket}" = "" ; then RUN_RACKET_CGC='$(RUN_THIS_RACKET_CGC)' RUN_RACKET_MMM='$(RUN_THIS_RACKET_MMM)' @@ -1770,6 +1781,8 @@ AC_SUBST(RUN_RACKET_MMM) AC_SUBST(RUN_RACKET_MAIN_VARIANT) AC_SUBST(CGC_IF_NEEDED_FOR_MMM) +AC_SUBST(MAKE_LOCAL_RACKET) + mk_needed_dir() { if test ! -d "$1" ; then From ee9d7979060afc44aab46ddcaab5bb87c2e5e9f0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 08:16:30 -0600 Subject: [PATCH 255/381] fix file descriptor handling for poll() without epoll() This problem could cause busy-waiting after a network connection on Android, for example. --- racket/src/racket/src/thread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index b31d01f414..48fe553724 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -4079,7 +4079,7 @@ static int check_fd_semaphores() hit = 1; SCHEME_VEC_ELS(v)[0] = scheme_false; } - pfd[i].revents -= (pfd[i].revents & POLLIN); + pfd[i].events -= (pfd[i].events & POLLIN); } if (pfd[i].revents & (POLLOUT | POLLHUP | POLLERR)) { s = SCHEME_VEC_ELS(v)[1]; @@ -4088,7 +4088,7 @@ static int check_fd_semaphores() hit = 1; SCHEME_VEC_ELS(v)[1] = scheme_false; } - pfd[i].revents -= (pfd[i].revents & POLLOUT); + pfd[i].events -= (pfd[i].events & POLLOUT); } if (SCHEME_FALSEP(SCHEME_VEC_ELS(v)[0]) && SCHEME_FALSEP(SCHEME_VEC_ELS(v)[1])) From a75bdbf0a12aa4b55803eb98374cdc91373a7f31 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 08:52:19 -0600 Subject: [PATCH 256/381] remove unused variable --- racket/src/racket/src/compile.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 49426e71a0..d214c90fef 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -1169,7 +1169,7 @@ if_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *er static Scheme_Object * with_cont_mark_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec) { - Scheme_Object *key, *val, *expr, *name, *orig_form = form, *value_name; + Scheme_Object *key, *val, *expr, *value_name; Scheme_Compile_Info recs[3]; Scheme_With_Continuation_Mark *wcm; int len; @@ -1194,8 +1194,6 @@ with_cont_mark_syntax(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_ scheme_compile_rec_done_local(rec, drec); - name = scheme_check_name_property(orig_form, value_name); - scheme_init_compile_recs(rec, drec, recs, 3); key = scheme_compile_expr(key, env, recs, 0); From 9768f632a2825704b56f47a3a272d49de528671d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 08:56:08 -0600 Subject: [PATCH 257/381] Disable static-library install for Windows or Mac OS X Also, OS X `strip` needs `-S` for archives, in case a static-library install is enabled. --- racket/src/configure | 23 ++++++++++++++++++----- racket/src/racket/configure.ac | 21 ++++++++++++++++++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/racket/src/configure b/racket/src/configure index 84167ff948..b4353468f8 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -1451,7 +1451,7 @@ Optional Features: --enable-shared create shared libraries (ok, but not recommended) --enable-dynlib same as --enable-shared --enable-lt= use instead of libtool; disable to use bundled - --enable-libs install static libraries, if any (enabled by default) + --enable-libs install static libraries (enabled by default for Unix) --enable-libffi use installed libffi (enabled by default for Unix) --enable-sdk= use Mac OS X 10.4 SDK directory --enable-sdk5= use Mac OS X 10.5 SDK directory @@ -2685,8 +2685,6 @@ fi # Check whether --enable-libs was given. if test "${enable_libs+set}" = set; then : enableval=$enable_libs; -else - enable_libs=yes fi @@ -3054,6 +3052,7 @@ show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping" +show_explicitly_enabled "${enable_libs}" "Installation of static libraries (if any)" show_explicitly_disabled "${enable_libs}" "Installation of static libraries (if any)" show_explicitly_disabled "${enable_mac64}" "64-bit Mac OS X" @@ -3178,6 +3177,7 @@ INSTALL_SETUP_RACKET_FLAGS= INSTALL_LIBS_ENABLE=no-install STRIP_DEBUG=":" +strip_debug_flags="" enable_strip_by_default=yes use_flag_pthread=yes @@ -4528,7 +4528,8 @@ if test "${enable_jit}" = "yes" ; then check_for_mprotect=yes fi -if test "${enable_libs}" = "yes" ; then +if test "${enable_libs}" != "no" ; then + # Canceled for some platforms below: INSTALL_LIBS_ENABLE=install fi @@ -4657,6 +4658,10 @@ case "$host_os" in GUI_CONFIG_PATH="../etc" skip_iconv_check=yes check_for_mprotect=no + # ".a" is typically not useful, since we always build a DLL: + if test "${enable_libs}" == "" ; then + INSTALL_LIBS_ENABLE=no-install + fi $as_echo "#define HAVE_STDINT_H 1" >>confdefs.h @@ -4738,6 +4743,14 @@ $as_echo "#define HAVE_STDINT_H 1" >>confdefs.h PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT" try_kqueue_syscall=yes + # Needed when stripping ".a"s: + strip_debug_flags=" -S" + + # ".a" is typically not useful, since we always build a ".dylib": + if test "${enable_libs}" == "" ; then + INSTALL_LIBS_ENABLE=no-install + fi + SO_SUFFIX=.dylib # Force 32-bit build unless mac64 is enabled: @@ -4936,7 +4949,7 @@ else fi # Used to add -S flag, but not all `strip' variants support it: - STRIP_DEBUG="$STRIP" + STRIP_DEBUG="${STRIP}${strip_debug_flags}" fi ############## C flags ################ diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 41e2e7aff9..8ad72a7af4 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -53,7 +53,7 @@ AC_ARG_ENABLE(natipkg, [ --enable-natipkg add "-natipkg" to library subp AC_ARG_ENABLE(shared, [ --enable-shared create shared libraries (ok, but not recommended)]) AC_ARG_ENABLE(dynlib, [ --enable-dynlib same as --enable-shared]) AC_ARG_ENABLE(lt, [ --enable-lt= use instead of libtool; disable to use bundled], LIBTOOLPROG="$enableval", enable_lt=default) -AC_ARG_ENABLE(libs, [ --enable-libs install static libraries, if any (enabled by default)], , enable_libs=yes) +AC_ARG_ENABLE(libs, [ --enable-libs install static libraries (enabled by default for Unix)]) AC_ARG_ENABLE(libffi, [ --enable-libffi use installed libffi (enabled by default for Unix)], , enable_libffi=default) @@ -325,6 +325,7 @@ show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping" +show_explicitly_enabled "${enable_libs}" "Installation of static libraries (if any)" show_explicitly_disabled "${enable_libs}" "Installation of static libraries (if any)" show_explicitly_disabled "${enable_mac64}" "64-bit Mac OS X" @@ -449,6 +450,7 @@ INSTALL_SETUP_RACKET_FLAGS= INSTALL_LIBS_ENABLE=no-install STRIP_DEBUG=":" +strip_debug_flags="" enable_strip_by_default=yes use_flag_pthread=yes @@ -652,7 +654,8 @@ if test "${enable_jit}" = "yes" ; then check_for_mprotect=yes fi -if test "${enable_libs}" = "yes" ; then +if test "${enable_libs}" != "no" ; then + # Canceled for some platforms below: INSTALL_LIBS_ENABLE=install fi @@ -781,6 +784,10 @@ case "$host_os" in GUI_CONFIG_PATH="../etc" skip_iconv_check=yes check_for_mprotect=no + # ".a" is typically not useful, since we always build a DLL: + if test "${enable_libs}" == "" ; then + INSTALL_LIBS_ENABLE=no-install + fi AC_DEFINE(HAVE_STDINT_H,1,[Have stdint.h]) if `which ${host}-windres > /dev/null` ; then WINDRES="${host}-windres" @@ -860,6 +867,14 @@ case "$host_os" in PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT" try_kqueue_syscall=yes + # Needed when stripping ".a"s: + strip_debug_flags=" -S" + + # ".a" is typically not useful, since we always build a ".dylib": + if test "${enable_libs}" == "" ; then + INSTALL_LIBS_ENABLE=no-install + fi + SO_SUFFIX=.dylib # Force 32-bit build unless mac64 is enabled: @@ -967,7 +982,7 @@ fi if test "${enable_strip}" = "yes" ; then AC_CHECK_TOOL([STRIP], [strip]) # Used to add -S flag, but not all `strip' variants support it: - STRIP_DEBUG="$STRIP" + STRIP_DEBUG="${STRIP}${strip_debug_flags}" fi ############## C flags ################ From 1ddaad8d582adea7874024baffd0b617ea63bf10 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 09:17:02 -0600 Subject: [PATCH 258/381] xform: accomodate tokens like "10_1" Those show up in the Mac OS X 10.11 SDK in `availability` annotations. Closes PR 15154 --- racket/collects/compiler/private/xform.rkt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/racket/collects/compiler/private/xform.rkt b/racket/collects/compiler/private/xform.rkt index 42b6988036..38052342fe 100644 --- a/racket/collects/compiler/private/xform.rkt +++ b/racket/collects/compiler/private/xform.rkt @@ -233,6 +233,9 @@ (define IS "(?:u|U|l|L)*") (define symbol-complex (trans (seqs L (arbno (alt L D))))) + + ;; Accomodate things like 10_1 in `availability` attributes: + (define pseudo-symbol-complex (trans (seqs (arbno D) "_" (arbno D)))) (define number-complex (trans (alt* @@ -376,6 +379,11 @@ (loop (cdar m) (cons (symbol (subbytes s (caar m) (cdar m))) result)))] + [(regexp-match-positions pseudo-symbol-complex s p) + => (lambda (m) + (loop (cdar m) + (cons (symbol (subbytes s (caar m) (cdar m))) + result)))] [(regexp-match-positions number-complex s p) => (lambda (m) (loop (cdar m) From 658bac7f5288fef595dc2464267b1fa904fdc069 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 09:40:43 -0600 Subject: [PATCH 259/381] note on catalogs and building from a tag Closes #1058. --- INSTALL.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/INSTALL.txt b/INSTALL.txt index 35be1bbb4e..3654772566 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -130,6 +130,12 @@ previously installed packages remain installed and are updated, while new packages are added. To uninstall previously selected package, use `raco pkg remove'. +To build anything other than the latest sources in the repository +(e.g., when building from the "v6.2.1" tag), you need a catalog +that's compatible with those sources. Note that a release distribution +is configured to use a catalog specific to that release, so you can +extract the catalog's URL from there. + Using `make' (or `make in-place') sets the installation's name to "development", unless the installation has been previously configured (i.e., unless the "racket/etc/config.rktd" file exists). The From 584920b3a671fa56b4ffb801f975cbb463b439e3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 13:53:44 -0600 Subject: [PATCH 260/381] GC: clarify page field overloadings Rename fields in a page record and split some of them with `union` to better document the intent of each field. This change is intended to have no effect on the GC's behavior. One tricky case is the line dropped around line 3542 of "newgc.c". That line reset `scan_boundary` (formerly `previous_size`), which on the surface is inconsistent with leving objects before the boundary without `marked` bits set. However, that line is reachable only when geneation-1 objects are being marked (objects newly moved there would not be unmarked), in which case `san_boundary` should already be reset. --- racket/src/racket/gc2/newgc.c | 138 ++++++++++++++++------------------ racket/src/racket/gc2/newgc.h | 21 +++++- 2 files changed, 80 insertions(+), 79 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index f4cf9b0d72..3e5cf359fd 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -73,7 +73,7 @@ enum { }; enum { - SIZE_CLASS_SMALL_PAGE = 0, + SIZE_CLASS_SMALL_PAGE = 0, /* can be a nursery page */ SIZE_CLASS_MED_PAGE = 1, SIZE_CLASS_BIG_PAGE = 2, SIZE_CLASS_BIG_PAGE_MARKED = 3, @@ -245,8 +245,6 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { seems to have been excessively conservative. */ #define FORCE_MAJOR_AFTER_COUNT 1000 -#define GEN0_ALLOC_SIZE(page) ((page)->previous_size) - /* This is the log base 2 of the size of one word, given in bytes */ #ifdef SIXTY_FOUR_BIT_INTEGERS # define LOG_WORD_SIZE 3 @@ -501,8 +499,8 @@ static void free_orphaned_page(NewGC *gc, mpage *tmp) { shared_pagemap_set(tmp->addr, round_to_apage_size(tmp->size), NULL); #endif - /* free_pages decrements gc->used_pages which is incorrect, since this is an orphaned page, - * so we use mmu_free_page directly */ + /* free_pages decrements gc->used_pages, which is incorrect since this is an orphaned page; + * so, we use mmu_free_page directly */ mmu_free_page(gc->mmu, tmp->addr, round_to_apage_size(tmp->size), page_mmu_type(tmp), page_mmu_protectable(tmp), @@ -745,7 +743,7 @@ inline static void pagemap_modify_with_size(PageMap pagemap, mpage *page, intptr } inline static void pagemap_modify(PageMap pagemap, mpage *page, mpage *val) { - intptr_t size = (page->size_class > 1) ? page->size : APAGE_SIZE; + intptr_t size = (page->size_class >= SIZE_CLASS_BIG_PAGE) ? page->size : APAGE_SIZE; pagemap_modify_with_size(pagemap, page, size, val); } @@ -843,26 +841,20 @@ static const char *zero_sized[4]; /* all 0-sized allocs get this */ inline static size_t real_page_size(mpage *page) { switch (page->size_class) { - case 0: /* SMALL_PAGE , GEN0_PAGE */ + case SIZE_CLASS_SMALL_PAGE: /* can be a GEN0_PAGE */ if (page->generation >= AGE_GEN_1) { return APAGE_SIZE; } - else { return GEN0_ALLOC_SIZE(page); } - case 1: /* MED PAGE */ + else { return page->alloc_size; } + case SIZE_CLASS_MED_PAGE: return APAGE_SIZE; - case 2: /* BIG PAGE */ - case 3: /* BIG PAGE MARKED */ + case SIZE_CLASS_BIG_PAGE: + case SIZE_CLASS_BIG_PAGE_MARKED: return round_to_apage_size(page->size); - default: /* BIG PAGE size_class 2 or 3 */ + default: printf("Error Page class %i doesn't exist\n", page->size_class); return 0; } } -#if 0 -static inline size_t size_in_apages(mpage *page) { - return (page->size_class > 1) ? (round_to_apage_size(page->size) / APAGE_SIZE) : 1; -} -#endif - static mpage *malloc_mpage() { mpage *page; @@ -1085,7 +1077,7 @@ static void *allocate_big(const size_t request_size_bytes, int type) return objptr; } } -#define MED_NEXT_SEARCH_SLOT(page) ((page)->previous_size) + inline static mpage *create_new_medium_page(NewGC *gc, const int sz, const int pos, int type) { mpage *page; int n, ty; @@ -1100,14 +1092,14 @@ inline static mpage *create_new_medium_page(NewGC *gc, const int sz, const int p page = malloc_mpage(); page->addr = addr; page->mmu_src_block = src_block; - page->size = sz; + page->obj_size = sz; page->size_class = SIZE_CLASS_MED_PAGE; page->page_type = PAGE_BIG; - MED_NEXT_SEARCH_SLOT(page) = PREFIX_SIZE; + page->med_search_start = PREFIX_SIZE; page->live_size = sz; GCVERBOSEPAGE(gc, "NEW MED PAGE", page); - for (n = MED_NEXT_SEARCH_SLOT(page); ((n + sz) <= APAGE_SIZE); n += sz) { + for (n = page->med_search_start; ((n + sz) <= APAGE_SIZE); n += sz) { objhead *info = (objhead *)PTR(NUM(page->addr) + n); info->dead = 1; info->size = gcBYTES_TO_WORDS(sz); @@ -1140,12 +1132,12 @@ inline static void *medium_page_realloc_dead_slot(NewGC *gc, const int sz, const ty = ((type == PAGE_ATOMIC) ? MED_PAGE_ATOMIC : MED_PAGE_NONATOMIC); for (page = gc->med_freelist_pages[ty][pos]; page; page = gc->med_freelist_pages[ty][pos] = page->prev) { - for (n = MED_NEXT_SEARCH_SLOT(page); ((n + sz) <= APAGE_SIZE); n += sz) { + for (n = page->med_search_start; ((n + sz) <= APAGE_SIZE); n += sz) { objhead * info = (objhead *)PTR(NUM(page->addr) + n); if (info->dead) { void *p; - MED_NEXT_SEARCH_SLOT(page) = (n + sz); + page->med_search_start = (n + sz); page->live_size += sz; info->dead = 0; @@ -1210,7 +1202,7 @@ static void *allocate_medium(const size_t request_size_bytes, const int type) objhead *info; page = create_new_medium_page(gc, sz, pos, type); - info = (objhead *)PTR(NUM(page->addr) + MED_NEXT_SEARCH_SLOT(page)); + info = (objhead *)PTR(NUM(page->addr) + page->med_search_start); info->dead = 0; info->type = type; @@ -1242,7 +1234,7 @@ inline static mpage *gen0_create_new_nursery_mpage(NewGC *gc, const size_t page_ page->mmu_src_block = src_block; page->size_class = SIZE_CLASS_SMALL_PAGE; page->size = PREFIX_SIZE; - GEN0_ALLOC_SIZE(page) = page_size; + page->alloc_size = page_size; if (gc->saved_allocator) { /* see MESSAGE ALLOCATION above */ orphan_page_accounting(gc, page_size); @@ -1305,11 +1297,11 @@ uintptr_t GC_make_jit_nursery_page(int count, uintptr_t *sz) { } inline static void gen0_free_jit_nursery_page(NewGC *gc, mpage *page) { - gen0_free_nursery_mpage(gc, page, GEN0_ALLOC_SIZE(page)); + gen0_free_nursery_mpage(gc, page, page->alloc_size); } inline static void gen0_free_mpage(NewGC *gc, mpage *page) { - gen0_free_nursery_mpage(gc, page, GEN0_ALLOC_SIZE(page)); + gen0_free_nursery_mpage(gc, page, page->alloc_size); } #define OVERFLOWS_GEN0(ptr) ((ptr) > GC_gen0_alloc_page_end) @@ -1359,7 +1351,7 @@ inline static void gen0_allocate_and_setup_new_page(NewGC *gc) { GC_gen0_alloc_page_ptr = NUM(new_mpage->addr) + new_mpage->size; ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); - GC_gen0_alloc_page_end = NUM(new_mpage->addr) + GEN0_ALLOC_SIZE(new_mpage); + GC_gen0_alloc_page_end = NUM(new_mpage->addr) + new_mpage->alloc_size; } inline static uintptr_t allocate_slowpath(NewGC *gc, size_t allocate_size, uintptr_t newptr) @@ -1374,7 +1366,7 @@ inline static uintptr_t allocate_slowpath(NewGC *gc, size_t allocate_size, uintp gc->gen0.curr_alloc_page = gc->gen0.curr_alloc_page->next; GC_gen0_alloc_page_ptr = NUM(gc->gen0.curr_alloc_page->addr) + gc->gen0.curr_alloc_page->size; ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); - GC_gen0_alloc_page_end = NUM(gc->gen0.curr_alloc_page->addr) + GEN0_ALLOC_SIZE(gc->gen0.curr_alloc_page); + GC_gen0_alloc_page_end = NUM(gc->gen0.curr_alloc_page->addr) + gc->gen0.curr_alloc_page->alloc_size; } else if (gc->avoid_collection) gen0_allocate_and_setup_new_page(gc); @@ -1937,7 +1929,7 @@ inline static void resize_gen0(NewGC *gc, uintptr_t new_size) gc->gen0.curr_alloc_page = gc->gen0.pages; GC_gen0_alloc_page_ptr = NUM(gc->gen0.curr_alloc_page->addr) + gc->gen0.curr_alloc_page->size; ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); - GC_gen0_alloc_page_end = NUM(gc->gen0.curr_alloc_page->addr) + GEN0_ALLOC_SIZE(gc->gen0.curr_alloc_page); + GC_gen0_alloc_page_end = NUM(gc->gen0.curr_alloc_page->addr) + gc->gen0.curr_alloc_page->alloc_size; /* set the two size variables */ gc->gen0.max_size = alloced_size; @@ -2021,7 +2013,7 @@ inline static int marked(NewGC *gc, const void *p) return 1; case SIZE_CLASS_SMALL_PAGE: if (page->generation >= AGE_GEN_1) { - if((NUM(page->addr) + page->previous_size) > NUM(p)) + if((NUM(page->addr) + page->scan_boundary) > NUM(p)) return 1; } /* else FALLTHROUGH */ @@ -2092,7 +2084,7 @@ static void dump_heap(NewGC *gc) if(collections >= 0) { for(page = gc->gen0.pages; page; page = page->next) { fprintf(dump, "Generation 0 Page (%p:%p - %p, size %i):\n", - page, page->addr, PTR(NUM(page->addr) + GEN0_ALLOC_SIZE(page)), page->size); + page, page->addr, PTR(NUM(page->addr) + page->alloc_size), page->size); dump_region(PAGE_START_VSS(page), PAGE_END_VSS(page)); } for(page = gc->gen0.big_pages; page; page = page->next) { @@ -2212,10 +2204,10 @@ static void *get_backtrace(mpage *page, void *ptr, int *kind) } if (page->size_class) { - if (page->size_class > 1) + if (page->size_class >= SIZE_CLASS_BIG_PAGE) ptr = BIG_PAGE_TO_OBJECT(page); else - ptr = MED_OBJHEAD_TO_OBJECT(ptr, page->size); + ptr = MED_OBJHEAD_TO_OBJECT(ptr, page->obj_size); } delta = PPTR(ptr) - PPTR(page->addr); @@ -3497,7 +3489,7 @@ void GC_mark2(void *pp, struct NewGC *gc) push_ptr(gc, TAG_AS_BIG_PAGE_PTR(p)); } else { /* A medium page. */ - objhead *info = MED_OBJHEAD(p, page->size); + objhead *info = MED_OBJHEAD(p, page->obj_size); if (info->mark) { GCDEBUG((DEBUGOUTF,"Not marking %p (already marked)\n", p)); RELEASE_PAGE_LOCK(is_a_master_page, page); @@ -3537,7 +3529,7 @@ void GC_mark2(void *pp, struct NewGC *gc) object masquerading as a tagged object, etc. So all we do is add the pointer to the mark queue and note on the page that we marked something on it*/ - if((NUM(page->addr) + page->previous_size) <= NUM(p)) { + if ((NUM(page->addr) + page->scan_boundary) <= NUM(p)) { GCDEBUG((DEBUGOUTF, "Marking %p (leaving alone)\n", p)); ohead->mark = 1; if (!page->marked_on) { @@ -3547,12 +3539,11 @@ void GC_mark2(void *pp, struct NewGC *gc) gc->modified_next = page; } } - page->previous_size = PREFIX_SIZE; page->live_size += ohead->size; record_backtrace(gc, page, p); mark_recur_or_push_ptr(gc, p, is_a_master_page); } else { - GCDEBUG((DEBUGOUTF, "Not marking %p (it's old; %p / %i)\n", p, page, page->previous_size)); + GCDEBUG((DEBUGOUTF, "Not marking %p (it's old; %p / %i)\n", p, page, page->scan_boundary)); } } else { /* this is a generation 0 or 1/2 object. This means that we do have @@ -3619,7 +3610,7 @@ void GC_mark2(void *pp, struct NewGC *gc) &work->mmu_src_block, 1); work->generation = AGE_GEN_1; work->page_type = type; - work->size = work->previous_size = PREFIX_SIZE; + work->size = work->scan_boundary = PREFIX_SIZE; work->marked_on = 1; work->modified_next = gc->modified_next; gc->modified_next = work; @@ -3781,7 +3772,7 @@ void *GC_resolve2(void *p, NewGC *gc) mpage *page = pagemap_find_page_for_marking(gc, p); objhead *info; - if(!page || page->size_class) + if (!page || (page->size_class > SIZE_CLASS_SMALL_PAGE)) return p; info = OBJPTR_TO_OBJHEAD(p); @@ -3814,7 +3805,7 @@ void GC_fixup2(void *pp, struct NewGC *gc) if (page) { objhead *info; - if (page->size_class) return; + if (page->size_class > SIZE_CLASS_SMALL_PAGE) return; info = OBJPTR_TO_OBJHEAD(p); /* assert: info->moved => info->mark */ @@ -3859,11 +3850,11 @@ int GC_is_partial(struct NewGC *gc) # define trace_page_t mpage # define trace_page_type(page) (page)->page_type static void *trace_pointer_start(mpage *page, void *p) { - if (page->size_class) { - if (page->size_class > 1) + if (page->size_class > SIZE_CLASS_SMALL_PAGE) { + if (page->size_class >= SIZE_CLASS_BIG_PAGE) return BIG_PAGE_TO_OBJECT(page); else - return MED_OBJHEAD_TO_OBJECT(p, page->size); + return MED_OBJHEAD_TO_OBJECT(p, page->obj_size); } else return p; } @@ -3873,7 +3864,7 @@ static void *trace_pointer_start(mpage *page, void *p) { # define TRACE_PAGE_PAIR PAGE_PAIR # define TRACE_PAGE_MALLOCFREE PAGE_TYPES # define TRACE_PAGE_BAD PAGE_TYPES -# define trace_page_is_big(page) (page)->size_class +# define trace_page_is_big(page) ((page)->size_class >= SIZE_CLASS_BIG_PAGE) # define trace_backpointer get_backtrace const char *trace_source_kind(int kind) { @@ -3977,7 +3968,7 @@ void GC_dump_with_traces(int flags, for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { for (page = gc->med_pages[ty][i]; page; page = page->next) { void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); - void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->size); + void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size); while(start <= end) { objhead *info = (objhead *)start; @@ -4052,7 +4043,7 @@ void GC_dump_with_traces(int flags, intptr_t count = 0, page_count = 0; for (page = gc->med_pages[ty][i]; page; page = page->next) { void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); - void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->size); + void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size); page_count++; @@ -4065,7 +4056,7 @@ void GC_dump_with_traces(int flags, } } GCWARN((GCOUTF, " %" PRIdPTR " [%" PRIdPTR "/%" PRIdPTR "]", - count, page_count, gc->med_pages[ty][i]->size)); + count, page_count, gc->med_pages[ty][i]->obj_size)); } } GCWARN((GCOUTF, "\n")); @@ -4137,37 +4128,34 @@ void *GC_next_tagged_start(void *p) /* garbage collection */ /*****************************************************************************/ -static void reset_gen1_page(NewGC *gc, mpage *work) -{ - if (gc->generations_available) { - work->mprotected = 0; - mmu_queue_write_unprotect_range(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); - } -} - -static void reset_gen1_pages_live_and_previous_sizes(NewGC *gc) +static void reset_gen1_pages_live_and_scan_boundaries(NewGC *gc) { mpage *work; int i; - GCDEBUG((DEBUGOUTF, "MAJOR COLLECTION - PREPPING PAGES - reset live_size, reset previous_size, unprotect.\n")); - /* we need to make sure that previous_size for every page is reset, so - we don't accidentally screw up the mark routine */ + /* Marking all objects, so make all pages writeable and set the scan + boundary on small pages to the beginning of the page. */ for(i = 0; i < PAGE_TYPES; i++) { for(work = gc->gen1_pages[i]; work; work = work->next) { - if(i != PAGE_ATOMIC && work->page_type != PAGE_ATOMIC) { - reset_gen1_page(gc, work); + if ((i != PAGE_ATOMIC) && (work->page_type != PAGE_ATOMIC)) { + if (work->mprotected) { + work->mprotected = 0; + mmu_queue_write_unprotect_range(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); + } } work->live_size = 0; - work->previous_size = PREFIX_SIZE; + work->scan_boundary = PREFIX_SIZE; } } for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { for (work = gc->med_pages[MED_PAGE_NONATOMIC][i]; work; work = work->next) { if (work->generation > AGE_GEN_0) { - reset_gen1_page(gc, work); + if (work->mprotected) { + work->mprotected = 0; + mmu_queue_write_unprotect_range(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); + } } } } @@ -4223,12 +4211,12 @@ static void mark_backpointers(NewGC *gc) } start += info->size; } - work->previous_size = PREFIX_SIZE; + work->scan_boundary = PREFIX_SIZE; gc->memory_in_use -= work->size; } else { /* medium page */ void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); - void **end = PPTR(NUM(work->addr) + APAGE_SIZE - work->size); + void **end = PPTR(NUM(work->addr) + APAGE_SIZE - work->obj_size); GC_ASSERT(work->size_class == SIZE_CLASS_MED_PAGE); @@ -4261,7 +4249,7 @@ mpage *allocate_compact_target(NewGC *gc, mpage *work) npage = malloc_mpage(); npage->addr = malloc_pages(gc, APAGE_SIZE, APAGE_SIZE, MMU_DIRTY, MMU_SMALL_GEN1, page_mmu_protectable(work), &npage->mmu_src_block, 1); - npage->previous_size = npage->size = PREFIX_SIZE; + npage->scan_boundary = npage->size = PREFIX_SIZE; npage->generation = AGE_GEN_1; npage->size_class = SIZE_CLASS_SMALL_PAGE; npage->page_type = work->page_type; @@ -4320,7 +4308,7 @@ inline static void do_heap_compact(NewGC *gc) if ((work->marked_on || work->marked_from) && !work->has_new) { /* then determine if we actually want to do compaction */ if (NO_BACKTRACE_AND(tic_tock - ? should_compact_page(gcWORDS_TO_BYTES(work->live_size),work->size) + ? should_compact_page(gcWORDS_TO_BYTES(work->live_size), work->size) : mmu_should_compact_page(gc->mmu, &work->mmu_src_block))) { void **start = PAGE_START_VSS(work); void **end = PAGE_END_VSS(work); @@ -4591,7 +4579,7 @@ static void repair_heap(NewGC *gc) memory_in_use += page->size; } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { - void **start = PPTR(NUM(page->addr) + page->previous_size); + void **start = PPTR(NUM(page->addr) + page->scan_boundary); void **end = PAGE_END_VSS(page); GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", @@ -4658,15 +4646,15 @@ static void repair_heap(NewGC *gc) break; } - page->previous_size = page->size; + page->scan_boundary = page->size; memory_in_use += page->size; } else { int non_dead; GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); - non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->size), need_fixup); - page->live_size = (page->size * non_dead); + non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size), need_fixup); + page->live_size = (page->obj_size * non_dead); memory_in_use += page->live_size; - page->previous_size = PREFIX_SIZE; /* start next block search at the beginning */ + page->med_search_start = PREFIX_SIZE; /* start next block search at the beginning */ if (page->generation == AGE_GEN_0) { /* Tell the clean-up phase to keep this one (even for a minor GC): */ page->marked_on = 1; @@ -5004,7 +4992,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->no_further_modifications = 1; if (gc->gc_full) - reset_gen1_pages_live_and_previous_sizes(gc); + reset_gen1_pages_live_and_scan_boundaries(gc); move_gen_half_pages_to_old(gc); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 4efa7de96b..84b09e7f8f 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -21,13 +21,26 @@ typedef struct mpage { #ifdef MZ_USE_PLACES uintptr_t page_lock; /* for master GC pages during marking */ #endif - uintptr_t previous_size; /* for med page, place to search for available block; for jit nursery, allocated size */ - uintptr_t size; /* big page size, med page element size, or nursery starting point */ + /* The `size` field is overleaded for related meanings: + - big page => the size of the allocated object + - small page, nursery, gen-1/2 => offset for next allocate = allocated bytes + PREFIX_SIZE + For a medium page, the `obj_size` field is used instead. */ + union { + uintptr_t size; /* size and/or allocation offset (see above) */ + uintptr_t obj_size; /* size of each object on a medium page */ + }; + union { + uintptr_t alloc_size; /* for a nursery: total size of the nursery */ + uintptr_t med_search_start; /* medium page: offset for searching for a free slot */ + uintptr_t scan_boundary; /* small gen1 page: during GC, boundary between objects that can be + left alone and that that will be scanned & fixed up; objects before + have cleared "mark" bits, while objects after (may) have "mark" bits sets */ + }; struct mpage *modified_next; /* next in chain of pages for backpointers, marks, etc. */ - unsigned short live_size; + unsigned short live_size; /* except for big pages, total size of live objects on the page */ unsigned char generation :2; unsigned char back_pointers :1; - unsigned char size_class :2; /* 0 => small; 1 => med; 2 => big; 3 => big marked */ + unsigned char size_class :2; unsigned char page_type :3; unsigned char marked_on :1; unsigned char marked_from :1; From 7ff1cf3619a2f117e1f9519e1a5912989654dac3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 15:16:30 -0600 Subject: [PATCH 261/381] avoid traversal of full page table when restoring mprotects Overlooked this traversal at 50df879e79. --- racket/src/racket/gc2/newgc.c | 106 +++++++++++++++++++++++----------- racket/src/racket/gc2/newgc.h | 6 +- 2 files changed, 78 insertions(+), 34 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 3e5cf359fd..c50784dfeb 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -61,14 +61,17 @@ enum { PAGE_ARRAY = 2, PAGE_PAIR = 3, PAGE_BIG = 4, - /* the number of page types: */ - PAGE_TYPES = 5 + /* the number of page types in then gen1 array: */ + PAGE_TYPES = 5, + /* medium page types: */ + PAGE_MED_ATOMIC = 6, + PAGE_MED_NONATOMIC = 7 }; enum { - MED_PAGE_NONATOMIC = 0, - MED_PAGE_ATOMIC = 1, - /* the number of medium-page types: */ + MED_PAGE_NONATOMIC_INDEX = 0, + MED_PAGE_ATOMIC_INDEX = 1, + /* the number of medium-page types in the array: */ MED_PAGE_TYPES = 2 }; @@ -1083,10 +1086,10 @@ inline static mpage *create_new_medium_page(NewGC *gc, const int sz, const int p int n, ty; void *src_block, *addr; - ty = ((type == PAGE_ATOMIC) ? MED_PAGE_ATOMIC : MED_PAGE_NONATOMIC); + ty = ((type == PAGE_ATOMIC) ? MED_PAGE_ATOMIC_INDEX : MED_PAGE_NONATOMIC_INDEX); addr = malloc_pages_maybe_fail(gc, APAGE_SIZE, APAGE_SIZE, MMU_ZEROED, MMU_BIG_MED, - (type == MED_PAGE_NONATOMIC) ? MMU_PROTECTABLE : MMU_NON_PROTECTABLE, + (ty == MED_PAGE_NONATOMIC_INDEX) ? MMU_PROTECTABLE : MMU_NON_PROTECTABLE, &src_block, sz); page = malloc_mpage(); @@ -1094,7 +1097,7 @@ inline static mpage *create_new_medium_page(NewGC *gc, const int sz, const int p page->mmu_src_block = src_block; page->obj_size = sz; page->size_class = SIZE_CLASS_MED_PAGE; - page->page_type = PAGE_BIG; + page->page_type = ((type == PAGE_ATOMIC) ? PAGE_MED_ATOMIC : PAGE_MED_NONATOMIC); page->med_search_start = PREFIX_SIZE; page->live_size = sz; GCVERBOSEPAGE(gc, "NEW MED PAGE", page); @@ -1129,7 +1132,7 @@ inline static void *medium_page_realloc_dead_slot(NewGC *gc, const int sz, const int n, ty; mpage *page; - ty = ((type == PAGE_ATOMIC) ? MED_PAGE_ATOMIC : MED_PAGE_NONATOMIC); + ty = ((type == PAGE_ATOMIC) ? MED_PAGE_ATOMIC_INDEX : MED_PAGE_NONATOMIC_INDEX); for (page = gc->med_freelist_pages[ty][pos]; page; page = gc->med_freelist_pages[ty][pos] = page->prev) { for (n = page->med_search_start; ((n + sz) <= APAGE_SIZE); n += sz) { @@ -2756,7 +2759,9 @@ inline static int page_mmu_type(mpage *page) { } inline static int page_mmu_protectable(mpage *page) { - return (page->page_type == PAGE_ATOMIC) ? MMU_NON_PROTECTABLE : MMU_PROTECTABLE; + return (((page->page_type == PAGE_ATOMIC) || (page->page_type == PAGE_MED_ATOMIC)) + ? MMU_NON_PROTECTABLE + : MMU_PROTECTABLE); } static void set_has_back_pointers(NewGC *gc, mpage *page) @@ -4037,7 +4042,7 @@ void GC_dump_with_traces(int flags, } for (ty = 0; ty < MED_PAGE_TYPES; ty++) { - GCWARN((GCOUTF, "Generation 1 [medium%s]:", (ty == MED_PAGE_ATOMIC) ? " atomic" : "")); + GCWARN((GCOUTF, "Generation 1 [medium%s]:", (ty == MED_PAGE_ATOMIC_INDEX) ? " atomic" : "")); for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { if (gc->med_pages[ty][i]) { intptr_t count = 0, page_count = 0; @@ -4150,7 +4155,7 @@ static void reset_gen1_pages_live_and_scan_boundaries(NewGC *gc) } for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { - for (work = gc->med_pages[MED_PAGE_NONATOMIC][i]; work; work = work->next) { + for (work = gc->med_pages[MED_PAGE_NONATOMIC_INDEX][i]; work; work = work->next) { if (work->generation > AGE_GEN_0) { if (work->mprotected) { work->mprotected = 0; @@ -4189,6 +4194,7 @@ static void mark_backpointers(NewGC *gc) work->mprotected = 0; mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); } + work->marked_from = 1; if (work->size_class == SIZE_CLASS_BIG_PAGE) { @@ -4534,6 +4540,8 @@ static void repair_heap(NewGC *gc) page = gc->modified_next; gc->modified_next = NULL; + gc->reprotect_next = NULL; + memory_in_use = gc->memory_in_use; need_fixup = gc->need_fixup; @@ -4656,7 +4664,7 @@ static void repair_heap(NewGC *gc) memory_in_use += page->live_size; page->med_search_start = PREFIX_SIZE; /* start next block search at the beginning */ if (page->generation == AGE_GEN_0) { - /* Tell the clean-up phase to keep this one (even for a minor GC): */ + /* Tell the clean-up phase to keep this one (needed even for a minor GC): */ page->marked_on = 1; GC_ASSERT(non_dead); /* otherwise, wouldn't have marked_on */ } @@ -4668,6 +4676,11 @@ static void repair_heap(NewGC *gc) set_has_back_pointers(gc, page); else page->back_pointers = 0; + + if ((page->page_type != PAGE_ATOMIC) && (page->page_type != PAGE_MED_ATOMIC)) { + page->reprotect_next = gc->reprotect_next; + gc->reprotect_next = page; + } } } @@ -4835,7 +4848,7 @@ static void unprotect_old_pages(NewGC *gc) } for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { - for (page = gc->med_pages[MED_PAGE_NONATOMIC][i]; page; page = page->next) { + for (page = gc->med_pages[MED_PAGE_NONATOMIC_INDEX][i]; page; page = page->next) { if (page->mprotected) { page->mprotected = 0; mmu_queue_write_unprotect_range(mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); @@ -4851,29 +4864,56 @@ static void protect_old_pages(NewGC *gc) { MMU *mmu = gc->mmu; mpage *page; - int i; - for (i = 0; i < PAGE_TYPES; i++) { - if (i != PAGE_ATOMIC) { - for (page = gc->gen1_pages[i]; page; page = page->next) { - if (page->page_type != PAGE_ATOMIC) { - if (!page->mprotected && !page->back_pointers) { - page->mprotected = 1; - mmu_queue_write_protect_range(mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); - } else if (QUEUED_MPROTECT_INFECTS_SMALL) - page->mprotected = 1; +#if 0 + /* Check that `reprotect_next` chain is correct: */ + { + int i; + int count = 0; + + for (i = 0; i < PAGE_TYPES; i++) { + if (i != PAGE_ATOMIC) { + for (page = gc->gen1_pages[i]; page; page = page->next) { + GC_ASSERT(page->generation != AGE_VACATED); + if (page->page_type != PAGE_ATOMIC) { + if (!page->mprotected) + count++; + } } } } - } - for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { - for (page = gc->med_pages[MED_PAGE_NONATOMIC][i]; page; page = page->next) { - if (!page->mprotected && !page->back_pointers) { - page->mprotected = 1; - mmu_queue_write_protect_range(mmu, page->addr, APAGE_SIZE, page_mmu_type(page), &page->mmu_src_block); - } else if (QUEUED_MPROTECT_INFECTS_MED) - page->mprotected = 1; + for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { + for (page = gc->med_pages[MED_PAGE_NONATOMIC_INDEX][i]; page; page = page->next) { + if (!page->mprotected) + count++; + } + } + + for (page = gc->reprotect_next; page; page = page->reprotect_next) { + count--; + } + + GC_ASSERT(!count); + } +#endif + + for (page = gc->reprotect_next; page; page = page->reprotect_next) { + GC_ASSERT(!page->mprotected); + GC_ASSERT(page->page_type != PAGE_ATOMIC); + GC_ASSERT(page->page_type != PAGE_MED_ATOMIC); + GC_ASSERT(page->generation != AGE_VACATED); + if (!page->back_pointers) { + page->mprotected = 1; + mmu_queue_write_protect_range(mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); + } else { + if (page->size_class == SIZE_CLASS_SMALL_PAGE) { + if (QUEUED_MPROTECT_INFECTS_SMALL) + page->mprotected = 1; + } else if (page->size_class == SIZE_CLASS_MED_PAGE) { + if (QUEUED_MPROTECT_INFECTS_MED) + page->mprotected = 1; + } } } @@ -5334,7 +5374,7 @@ static void free_gc(NewGC *gc) } } for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { - for (work = gc->med_pages[MED_PAGE_NONATOMIC][i]; work; work = work->next) { + for (work = gc->med_pages[MED_PAGE_NONATOMIC_INDEX][i]; work; work = work->next) { if (work->mprotected) mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); } diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 84b09e7f8f..36f438dbea 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -14,6 +14,8 @@ typedef struct mpage { struct mpage *prev; void *addr; void *mmu_src_block; + struct mpage *modified_next; /* next in chain of pages for backpointers, marks, etc. */ + struct mpage *reprotect_next; /* next in a chain of pages that need to be re-protected */ #ifdef MZ_GC_BACKTRACE void **backtrace; void *backtrace_page_src; @@ -36,7 +38,6 @@ typedef struct mpage { left alone and that that will be scanned & fixed up; objects before have cleared "mark" bits, while objects after (may) have "mark" bits sets */ }; - struct mpage *modified_next; /* next in chain of pages for backpointers, marks, etc. */ unsigned short live_size; /* except for big pages, total size of live objects on the page */ unsigned char generation :2; unsigned char back_pointers :1; @@ -157,6 +158,9 @@ typedef struct NewGC { /* linked list of pages with back pointers to be traversed in a minor collection, etc.: */ struct mpage *modified_next; + /* linked list of pages that need to be given write protection at + the end of the GC cycle: */ + struct mpage *reprotect_next; MarkSegment *mark_stack; From bcc65ac92ee7a7246bfc8d87eae85c501d8888c2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 16:49:58 -0600 Subject: [PATCH 262/381] GC: separate old-generation finalizers from now ones Avoiding a traversals of old-generation finalizers can save a couple of milliseconds for a minor GC in DrRacket. --- racket/src/racket/gc2/fnls.c | 115 ++++++++++++++++++++++++---------- racket/src/racket/gc2/newgc.c | 33 +++++++--- racket/src/racket/gc2/newgc.h | 3 +- 3 files changed, 109 insertions(+), 42 deletions(-) diff --git a/racket/src/racket/gc2/fnls.c b/racket/src/racket/gc2/fnls.c index c198316e9f..4a893e56b5 100644 --- a/racket/src/racket/gc2/fnls.c +++ b/racket/src/racket/gc2/fnls.c @@ -8,6 +8,7 @@ num_fnls Requires: is_finalizable_page(gc, p) + is_in_gen_half(p, gc) park */ @@ -22,6 +23,41 @@ #undef splay_insert #undef splay_delete +static void remove_finalizer(Fnl *fnl, int gen0, GCTYPE *gc) +{ + if (fnl->prev) + fnl->prev->next = fnl->next; + else { + if (gen0) + gc->gen0_finalizers = fnl->next; + else + gc->finalizers = fnl->next; + } + if (fnl->next) + fnl->next->prev = fnl->prev; + + if (gen0) + gc->splayed_gen0_finalizers = fnl_splay_delete((intptr_t)fnl->p, gc->splayed_gen0_finalizers); + else + gc->splayed_finalizers = fnl_splay_delete((intptr_t)fnl->p, gc->splayed_finalizers); +} + +static void add_finalizer(Fnl *fnl, int gen0, GCTYPE *gc) +{ + fnl->next = (gen0 ? gc->gen0_finalizers : gc->finalizers); + fnl->prev = NULL; + if (fnl->next) + fnl->next->prev = fnl; + + if (gen0) { + gc->gen0_finalizers = fnl; + gc->splayed_gen0_finalizers = fnl_splay_insert((intptr_t)fnl->p, fnl, gc->splayed_gen0_finalizers); + } else { + gc->finalizers = fnl; + gc->splayed_finalizers = fnl_splay_insert((intptr_t)fnl->p, fnl, gc->splayed_finalizers); + } +} + void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *data), void *data, void (**oldf)(void *p, void *data), void **olddata) @@ -36,8 +72,20 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d return; } - gc->splayed_finalizers = fnl_splay((intptr_t)p, gc->splayed_finalizers); - fnl = gc->splayed_finalizers; + gc->splayed_gen0_finalizers = fnl_splay((intptr_t)p, gc->splayed_gen0_finalizers); + fnl = gc->splayed_gen0_finalizers; + if (!fnl || (fnl->p != p)) { + gc->splayed_finalizers = fnl_splay((intptr_t)p, gc->splayed_finalizers); + fnl = gc->splayed_finalizers; + if (!fnl || (fnl->p != p)) + fnl = NULL; + else { + /* since we're mutating this finalizer, move it to the gen0 list and tree */ + remove_finalizer(fnl, 0, gc); + add_finalizer(fnl, 1, gc); + } + } + if (fnl && (fnl->p == p)) { if (oldf) *oldf = fnl->f; if (olddata) *olddata = fnl->data; @@ -47,15 +95,8 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d fnl->eager_level = level; } else { /* remove finalizer */ - if (fnl->prev) - fnl->prev->next = fnl->next; - else - gc->finalizers = fnl->next; - if (fnl->next) - fnl->next->prev = fnl->prev; - + remove_finalizer(fnl, 1, gc); --gc->num_fnls; - gc->splayed_finalizers = fnl_splay_delete((intptr_t)p, gc->splayed_finalizers); } return; } @@ -79,7 +120,6 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d gc->park[0] = NULL; gc->park[1] = NULL; - fnl->p = p; fnl->f = f; fnl->data = data; @@ -103,32 +143,43 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d } #endif - /* push finalizer */ - fnl->next = gc->finalizers; - fnl->prev = NULL; - if (gc->finalizers) { - gc->finalizers->prev = fnl; - } - gc->finalizers = fnl; - - gc->splayed_finalizers = fnl_splay_insert((intptr_t)p, fnl, gc->splayed_finalizers); - + add_finalizer(fnl, 1, gc); gc->num_fnls++; } -static void reset_finalizer_tree(GCTYPE *gc) - /* After a GC, rebuild the splay tree, since object addresses - have moved. */ +static void merge_finalizer_trees(GCTYPE *gc) +/* For a full GC, move all finalizers to the gen0 list */ { - Fnl *fnl; - Fnl *prev = NULL; + Fnl *fnl, *next; - gc->splayed_finalizers = NULL; - - for (fnl = gc->finalizers; fnl; fnl = fnl->next) { - fnl->prev = prev; - gc->splayed_finalizers = fnl_splay_insert((intptr_t)fnl->p, fnl, gc->splayed_finalizers); - prev = fnl; + for (fnl = gc->finalizers; fnl; fnl = next) { + next = fnl->next; + add_finalizer(fnl, 1, gc); } + + gc->finalizers = NULL; + gc->splayed_finalizers = NULL; } +static void reset_finalizer_tree(GCTYPE *gc) +/* After a GC, move gen0 finalizers to the old finalizer list. Note + that the old gen0 splay tree is otherwise broken, since object + addresses have moved. */ +{ + Fnl *fnl, *next; + + fnl = gc->gen0_finalizers; + gc->gen0_finalizers = NULL; + gc->splayed_gen0_finalizers = NULL; + + for (; fnl; fnl = next) { + next = fnl->next; + if (is_in_gen_half(fnl, gc) + || is_in_gen_half(fnl->f, gc) + || is_in_gen_half(fnl->data, gc)) + add_finalizer(fnl, 1, gc); + else + add_finalizer(fnl, 0, gc); + } + +} diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index c50784dfeb..40748c32bc 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2367,18 +2367,30 @@ static int is_finalizable_page(NewGC *gc, void *p) return !!pagemap_find_page(gc->page_maps, p); } +static int is_in_gen_half(void *p, NewGC *gc) +{ + mpage *page; + + if (gc->gc_full) + return 0; + + page = pagemap_find_page(gc->page_maps, p); + + return (page && (page->generation == AGE_GEN_HALF)); +} + #include "fnls.c" inline static void mark_finalizer_structs(NewGC *gc) { Fnl *fnl; - set_backtrace_source(gc, &gc->finalizers, BT_ROOT); - gcMARK2(gc->finalizers, gc); - for(fnl = gc->finalizers; fnl; fnl = fnl->next) { + set_backtrace_source(gc, &gc->gen0_finalizers, BT_ROOT); + gcMARK2(gc->gen0_finalizers, gc); + for(fnl = gc->gen0_finalizers; fnl; fnl = fnl->next) { set_backtrace_source(gc, fnl, BT_FINALIZER); gcMARK2(fnl->data, gc); - set_backtrace_source(gc, &gc->finalizers, BT_ROOT); + set_backtrace_source(gc, &gc->gen0_finalizers, BT_ROOT); gcMARK2(fnl->next, gc); } @@ -2388,7 +2400,7 @@ inline static void mark_finalizer_structs(NewGC *gc) set_backtrace_source(gc, fnl, BT_FINALIZER); gcMARK2(fnl->data, gc); gcMARK2(fnl->p, gc); - set_backtrace_source(gc, &gc->finalizers, BT_ROOT); + set_backtrace_source(gc, &gc->gen0_finalizers, BT_ROOT); gcMARK2(fnl->next, gc); } } @@ -2398,10 +2410,10 @@ inline static void repair_finalizer_structs(NewGC *gc) Fnl *fnl; /* repair the base parts of the list */ - gcFIXUP2(gc->finalizers, gc); + gcFIXUP2(gc->gen0_finalizers, gc); gcFIXUP2(gc->run_queue, gc); /* then repair the stuff inside them */ - for(fnl = gc->finalizers; fnl; fnl = fnl->next) { + for(fnl = gc->gen0_finalizers; fnl; fnl = fnl->next) { gcFIXUP2(fnl->data, gc); gcFIXUP2(fnl->p, gc); gcFIXUP2(fnl->next, gc); @@ -2416,7 +2428,7 @@ inline static void repair_finalizer_structs(NewGC *gc) inline static void check_finalizers(NewGC *gc, int level) { - Fnl *work = GC_resolve2(gc->finalizers, gc); + Fnl *work = GC_resolve2(gc->gen0_finalizers, gc); Fnl *prev = NULL; GCDEBUG((DEBUGOUTF, "CFNL: Checking level %i finalizers\n", level)); @@ -2432,7 +2444,7 @@ inline static void check_finalizers(NewGC *gc, int level) if (prev) prev->next = next; else - gc->finalizers = next; + gc->gen0_finalizers = next; if (next) next->prev = work->prev; work->prev = NULL; /* queue is singly-linked */ @@ -5034,6 +5046,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->gc_full) reset_gen1_pages_live_and_scan_boundaries(gc); + if (gc->gc_full) + merge_finalizer_trees(gc); + move_gen_half_pages_to_old(gc); init_weak_boxes(gc); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 36f438dbea..0e86dbc228 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -248,9 +248,10 @@ typedef struct NewGC { GC_Immobile_Box *immobile_boxes; - /* Common with CompactGC */ Fnl *finalizers; Fnl *splayed_finalizers; + Fnl *gen0_finalizers; + Fnl *splayed_gen0_finalizers; int num_fnls; void *park[2]; From 47776f343db1ebdd6a4761e3e6267eb83bbe9eab Mon Sep 17 00:00:00 2001 From: Spencer Florence Date: Mon, 14 Sep 2015 16:24:38 -0500 Subject: [PATCH 263/381] make sure git checkout have correct perms --- racket/collects/net/git-checkout.rkt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index 4ab3c09e9a..fbaebec499 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -676,6 +676,7 @@ #"100755" #"755") (copy-object tmp (this-object-location) + mode (build-path dest-dir fn))] [(#"40000" #"040000") (extract-tree id obj-ids tmp (build-path dest-dir fn))] @@ -938,8 +939,8 @@ [else (call-with-input-file* (build-path (tmp-info-dir tmp) location) proc)])) -;; copy-object : tmp-info location path -> void -(define (copy-object tmp location dest-file) +;; copy-object : tmp-info location bytes path -> void +(define (copy-object tmp location mode dest-file) (cond [(pair? location) (define bstr (object->bytes tmp location)) @@ -950,7 +951,12 @@ [else (copy-file (build-path (tmp-info-dir tmp) location) dest-file - #t)])) + #t)]) + (define perms + (case mode + [(#"755" #"100755") #o755] + [(#"644" #"100644") #o644])) + (file-or-directory-permissions dest-file perms)) ;; object->bytes : tmp-info location -> bytes (define (object->bytes tmp location) From 47f36952d6f76d28b45b12c734f8e30297bccf3a Mon Sep 17 00:00:00 2001 From: Spencer Florence Date: Mon, 14 Sep 2015 16:45:40 -0500 Subject: [PATCH 264/381] removed duplicate case --- racket/collects/net/git-checkout.rkt | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index fbaebec499..6bf3ba65d6 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -671,13 +671,16 @@ (when id (define (this-object-location) (object-location (hash-ref obj-ids id))) - (case (datum-intern-literal mode) - [(#"100644" #"644" - #"100755" #"755") + (define (copy-this-object perms) (copy-object tmp (this-object-location) - mode - (build-path dest-dir fn))] + perms + (build-path dest-dir fn))) + (case (datum-intern-literal mode) + [(#"100755") #"755" + (copy-this-object #o755)] + [(#"100644" #"644") + (copy-this-object #o644)] [(#"40000" #"040000") (extract-tree id obj-ids tmp (build-path dest-dir fn))] [(#"120000") @@ -939,8 +942,8 @@ [else (call-with-input-file* (build-path (tmp-info-dir tmp) location) proc)])) -;; copy-object : tmp-info location bytes path -> void -(define (copy-object tmp location mode dest-file) +;; copy-object : tmp-info location integer path -> void +(define (copy-object tmp location perms dest-file) (cond [(pair? location) (define bstr (object->bytes tmp location)) @@ -952,10 +955,6 @@ (copy-file (build-path (tmp-info-dir tmp) location) dest-file #t)]) - (define perms - (case mode - [(#"755" #"100755") #o755] - [(#"644" #"100644") #o644])) (file-or-directory-permissions dest-file perms)) ;; object->bytes : tmp-info location -> bytes From 7ee29b02394a20e6241efae52242768c929a4c96 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 19 Sep 2015 20:24:23 -0500 Subject: [PATCH 265/381] Revert permissions change because of appveyer error (that I should have seen before pushing, sorry) This reverts commit 47f36952d6f76d28b45b12c734f8e30297bccf3a. This reverts commit 47776f343db1ebdd6a4761e3e6267eb83bbe9eab. --- racket/collects/net/git-checkout.rkt | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index 6bf3ba65d6..4ab3c09e9a 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -671,16 +671,12 @@ (when id (define (this-object-location) (object-location (hash-ref obj-ids id))) - (define (copy-this-object perms) + (case (datum-intern-literal mode) + [(#"100644" #"644" + #"100755" #"755") (copy-object tmp (this-object-location) - perms - (build-path dest-dir fn))) - (case (datum-intern-literal mode) - [(#"100755") #"755" - (copy-this-object #o755)] - [(#"100644" #"644") - (copy-this-object #o644)] + (build-path dest-dir fn))] [(#"40000" #"040000") (extract-tree id obj-ids tmp (build-path dest-dir fn))] [(#"120000") @@ -942,8 +938,8 @@ [else (call-with-input-file* (build-path (tmp-info-dir tmp) location) proc)])) -;; copy-object : tmp-info location integer path -> void -(define (copy-object tmp location perms dest-file) +;; copy-object : tmp-info location path -> void +(define (copy-object tmp location dest-file) (cond [(pair? location) (define bstr (object->bytes tmp location)) @@ -954,8 +950,7 @@ [else (copy-file (build-path (tmp-info-dir tmp) location) dest-file - #t)]) - (file-or-directory-permissions dest-file perms)) + #t)])) ;; object->bytes : tmp-info location -> bytes (define (object->bytes tmp location) From 6dfc20d3ecb10f48bfed8317a6855add7879f463 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 19 Sep 2015 19:25:34 -0600 Subject: [PATCH 266/381] fix inferred-name propagation for internal-definition contexts Set the name while checking for an immediate expansion when no other forms follow. --- pkgs/racket-test-core/tests/racket/name.rktl | 10 ++++++++++ racket/src/racket/src/compile.c | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/pkgs/racket-test-core/tests/racket/name.rktl b/pkgs/racket-test-core/tests/racket/name.rktl index 03a634be38..151460f0f6 100644 --- a/pkgs/racket-test-core/tests/racket/name.rktl +++ b/pkgs/racket-test-core/tests/racket/name.rktl @@ -134,4 +134,14 @@ 5)) #rx"^(?!.*unmentionable)") + +(test 'norm values + (let-syntax ([m (lambda (stx) + #`'#,(syntax-local-name))]) + (define norm + (let () + (define x 8) + (m))) + norm)) + (report-errs) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index d214c90fef..47a046d2e6 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -5918,12 +5918,17 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, int more = 1, is_last; is_last = SCHEME_STX_NULLP(SCHEME_STX_CDR(forms)); + if (is_last) + env->value_name = orig_vname; result = forms; /* Check for macro expansion, which could mask the real define-values, define-syntax, etc.: */ first = scheme_check_immediate_macro(first, env, rec, drec, &gval, is_last); + + if (is_last) + env->value_name = NULL; if (SAME_OBJ(gval, scheme_begin_syntax)) { /* Inline content */ @@ -6141,7 +6146,11 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, first = scheme_datum_to_syntax(first, forms, forms, 0, 0); SCHEME_EXPAND_OBSERVE_NEXT(env->observer); is_last = SCHEME_STX_NULLP(SCHEME_STX_CDR(result)); + if (is_last) + env->value_name = orig_vname; first = scheme_check_immediate_macro(first, env, rec, drec, &gval, is_last); + if (is_last) + env->value_name = NULL; more = 1; if (NOT_SAME_OBJ(gval, scheme_define_values_syntax) && NOT_SAME_OBJ(gval, scheme_define_syntaxes_syntax)) { From 8d43c73a0c4055f3d80dbfda7d97870034947039 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 20 Sep 2015 17:06:35 -0600 Subject: [PATCH 267/381] windows: use same scheme_setjmp() protocol with all compilers --- racket/src/racket/sconfig.h | 4 +--- racket/src/worksp/libracket/libracket.vcproj | 13 +++++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/sconfig.h b/racket/src/racket/sconfig.h index 87eca16d2b..2c4455743d 100644 --- a/racket/src/racket/sconfig.h +++ b/racket/src/racket/sconfig.h @@ -658,9 +658,7 @@ # define DO_STACK_CHECK # define WINDOWS_FIND_STACK_BOUNDS -# if !defined(_WIN64) || (_MSC_VER >= 1600) || defined(__MINGW32__) -# define USE_MZ_SETJMP -# endif +# define USE_MZ_SETJMP # define WINDOWS_DYNAMIC_LOAD diff --git a/racket/src/worksp/libracket/libracket.vcproj b/racket/src/worksp/libracket/libracket.vcproj index 65c58ca59a..6fba1d13fa 100644 --- a/racket/src/worksp/libracket/libracket.vcproj +++ b/racket/src/worksp/libracket/libracket.vcproj @@ -503,6 +503,19 @@ RelativePath="..\..\racket\src\mzsj86.c" > + + + + + From 15797a79516ef8aa100e5a06363cd8224d3537a9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 20 Sep 2015 19:17:15 -0600 Subject: [PATCH 268/381] Windows: use same TLS strategy for both VC and MinGW in 64-bit mode --- racket/src/racket/include/schthread.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/include/schthread.h b/racket/src/racket/include/schthread.h index e60de86483..db10d94214 100644 --- a/racket/src/racket/include/schthread.h +++ b/racket/src/racket/include/schthread.h @@ -28,8 +28,12 @@ extern "C" { #if defined(MZ_USE_PLACES) || defined(MZ_USE_FUTURES) # define USE_THREAD_LOCAL # ifdef _WIN32 -# if defined(_WIN64) && !defined(__MINGW32__) -# define THREAD_LOCAL __declspec(thread) +# if defined(_WIN64) +# if defined(__MINGW32__) +# define THREAD_LOCAL __thread +# else +# define THREAD_LOCAL __declspec(thread) +# endif # define MZ_THREAD_EXTERN extern # define IMPLEMENT_THREAD_LOCAL_EXTERNALLY_VIA_PROC # else From b37c07a28035b1a9c0299fd097e7d029cf5f883a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 20 Sep 2015 19:40:59 -0600 Subject: [PATCH 269/381] Windows: generate "lib/msvc" content from cross-compile --- racket/src/racket/Makefile.in | 16 ++++++++++++++-- racket/src/racket/dynsrc/Makefile.in | 17 +++++++++++++++-- racket/src/racket/gc2/Makefile.in | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 3055055387..396a2eff78 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -221,10 +221,10 @@ lib/libracketxxxxxxx.dll: lib/libmzgcxxxxxxx.dll libracket.@LIBSFX@ mzsj86g.o @MZLINKER@ -shared -o lib/libracketxxxxxxx.dll mzsj86g.o -Wl,--output-def -Wl,libracket.def -Wl,--whole-archive libracket.@LIBSFX@ -Wl,--no-whole-archive -lshell32 -luser32 -lws2_32 lib/libmzgcxxxxxxx.dll -static-libgcc libracket.dll.a: lib/libracketxxxxxxx.dll - @DLLTOOL@ --def libracket.def -D libracketxxxxxxx.dll --output-delaylib libracket.dll.a + @DLLTOOL@ --def libracket.def -D libracketxxxxxxx.dll --output-exp libracketxxxxxxx.exp --output-lib libracketxxxxxxx.lib --output-delaylib libracket.dll.a libmzgc.dll.a: lib/libmzgcxxxxxxx.dll - @DLLTOOL@ --def libmzgc.def -D libmzgcxxxxxxx.dll --output-delaylib libmzgc.dll.a + @DLLTOOL@ --def libmzgc.def -D libmzgcxxxxxxx.dll --output-lib libmzgcxxxxxxx.lib --output-exp libmzgcxxxxxxx.lib --output-delaylib libmzgc.dll.a rres.o : $(srcdir)/../worksp/racket/racket.rc @WINDRES@ -i $(srcdir)/../worksp/racket/racket.rc -o rres.o @@ -445,6 +445,13 @@ mingw-install: cd ..; cp racket/MzCOM.tlb "$(DESTDIR)$(libpltdir)/MzCOM.tlb" mingw-install-cgc: + cd ..; mkdir -p "$(DESTDIR)$(libdir)/msvc" + cd ..; $(ICP) racket/libmzgcxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libmzgcxxxxxxx.lib" + cd ..; $(ICP) racket/libmzgcxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libmzgcxxxxxxx.exp" + cd ..; $(ICP) racket/libracketxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libracketxxxxxxx.lib" + cd ..; $(ICP) racket/libracketxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libracketxxxxxxx.exp" + cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/msvc/mzdyn.obj" + cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/msvc/mzdyn.exp" cd ..; $(ICP) racket/lib/libmzgcxxxxxxx.dll "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" cd ..; $(ICP) racket/lib/libracketxxxxxxx.dll "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll" cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" @@ -459,6 +466,11 @@ mingw-install-cgc-final: $(NOOP) mingw-install-3m: + cd ..; mkdir -p "$(DESTDIR)$(libdir)/msvc" + cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libracket3mxxxxxxx.lib" + cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libracket3mxxxxxxx.exp" + cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/msvc/mzdyn3m.obj" + cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/msvc/mzdyn3m.exp" cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(ICP) racket/mzcom@MMM@ "$(DESTDIR)$(libdir)/MzCOM@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(ICP) racket/lib/libracket3mxxxxxxx.dll "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll" diff --git a/racket/src/racket/dynsrc/Makefile.in b/racket/src/racket/dynsrc/Makefile.in index 2fbfa887dd..ccaa261257 100644 --- a/racket/src/racket/dynsrc/Makefile.in +++ b/racket/src/racket/dynsrc/Makefile.in @@ -23,13 +23,21 @@ CFLAGS = @CFLAGS@ @COMPFLAGS@ CPPFLAGS = @PREFLAGS@ ALL_CFLAGS = $(CFLAGS) $(CPPFLAGS) -I$(builddir)/.. -I$(srcdir)/../include -I$(srcdir)/../src @MZOPTIONS@ -dynlib: +dynlib@NOT_MINGW@: $(MAKE) ../mzdyn.o $(MAKE) ../starter@EXE_SUFFIX@ -dynlib3m: +dynlib@MINGW@: + $(MAKE) dynlib@NOT_MINGW@ + $(MAKE) ../mzdyn.exp + +dynlib3m@NOT_MINGW@: $(MAKE) ../mzdyn3m.o +dynlib3m@MINGW@: + $(MAKE) dynlib3m@NOT_MINGW@ + $(MAKE) ../mzdyn3m.exp + dynexample: $(MAKE) ../dynexmpl.so @@ -65,6 +73,11 @@ sres.o: smrres.o: @WINDRES@ -DMRSTART -i $(srcdir)/../../worksp/starters/start.rc -o smrres.o +../mzdyn.exp: ../mzdyn.o + @DLLTOOL@ --output-exp ../mzdyn.exp ../mzdyn.o +../mzdyn3m.exp: ../mzdyn3m.o + @DLLTOOL@ --output-exp ../mzdyn3m.exp ../mzdyn3m.o + # Cygwin ######################################## ILIBDIR = $(libpltdir) diff --git a/racket/src/racket/gc2/Makefile.in b/racket/src/racket/gc2/Makefile.in index 42fb655448..4b5c53545a 100644 --- a/racket/src/racket/gc2/Makefile.in +++ b/racket/src/racket/gc2/Makefile.in @@ -529,7 +529,7 @@ $(MZFWMMM): ../libracket3m.@LIBSFX@ @MZLINKER@ -shared -o ../lib/libracket3mxxxxxxx.dll ../mzsj86g.o -Wl,--output-def -Wl,libracket3m.def -Wl,--whole-archive ../libracket3m.@LIBSFX@ -Wl,--no-whole-archive -lshell32 -luser32 -lws2_32 -static-libgcc libracket3m.dll.a: ../lib/libracket3mxxxxxxx.dll - @DLLTOOL@ --def libracket3m.def -D libracket3mxxxxxxx.dll --output-delaylib libracket3m.dll.a + @DLLTOOL@ --def libracket3m.def -D libracket3mxxxxxxx.dll --output-exp libracket3mxxxxxxx.exp --output-lib libracket3mxxxxxxx.lib --output-delaylib libracket3m.dll.a MW_RACKET_LIBS = gc2/libracket3m.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgcc From 1d5b34f48bdaba2ade103a6b3eca638793c78597 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 20 Sep 2015 20:57:45 -0600 Subject: [PATCH 270/381] auto-detect when `strip -S` works for archives Otherwise, don't try to strip archives such as "libracket3m.a". --- racket/src/configure | 38 ++++++++++++++++++++++++++++++---- racket/src/racket/Makefile.in | 7 ++++--- racket/src/racket/configure.ac | 26 +++++++++++++++++++---- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/racket/src/configure b/racket/src/configure index b4353468f8..6415cd57ca 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -712,6 +712,7 @@ PLAIN_CC MZLINKER REZ CC_FOR_BUILD +STRIP_LIB_DEBUG STRIP_DEBUG ARFLAGS STATIC_AR @@ -3177,6 +3178,7 @@ INSTALL_SETUP_RACKET_FLAGS= INSTALL_LIBS_ENABLE=no-install STRIP_DEBUG=":" +STRIP_LIB_DEBUG=":" strip_debug_flags="" enable_strip_by_default=yes @@ -4743,9 +4745,6 @@ $as_echo "#define HAVE_STDINT_H 1" >>confdefs.h PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT" try_kqueue_syscall=yes - # Needed when stripping ".a"s: - strip_debug_flags=" -S" - # ".a" is typically not useful, since we always build a ".dylib": if test "${enable_libs}" == "" ; then INSTALL_LIBS_ENABLE=no-install @@ -4855,6 +4854,11 @@ if test "${enable_strip}" = "" ; then fi fi +try_archive_conftest() +{ + $AR $ARFLAGS conftest.a conftest.$OBJEXT > /dev/null 2>&1 +} + if test "${enable_strip}" = "yes" ; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -4949,7 +4953,32 @@ else fi # Used to add -S flag, but not all `strip' variants support it: - STRIP_DEBUG="${STRIP}${strip_debug_flags}" + STRIP_DEBUG="${STRIP}" + if test "${INSTALL_LIBS_ENABLE}" = "install" ; then + # Can only support library stripping if something like "-S" is available: + msg="for strip -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } + set_strip_lib=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int f() { return 0; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + try_archive_conftest +else + set_strip_lib=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test conftest.a ; then + if "${STRIP_DEBUG}" -S conftest.a > /dev/null 2>&1 ; then + STRIP_LIB_DEBUG="${STRIP_DEBUG} -S" + set_strip_lib=yes + fi + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $set_strip_lib" >&5 +$as_echo "$set_strip_lib" >&6; } + fi fi ############## C flags ################ @@ -6880,6 +6909,7 @@ LIBS="$LIBS $EXTRALIBS" + mk_needed_dir() diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 396a2eff78..2d8e4c750d 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -37,6 +37,7 @@ ARFLAGS = @ARFLAGS@ RANLIB = @RANLIB@ STRIP_DEBUG = @STRIP_DEBUG@ +STRIP_LIB_DEBUG = @STRIP_LIB_DEBUG@ ARLIBFLAGS = @LDFLAGS@ @LIBS@ @@ -406,8 +407,8 @@ unix-install-cgc: unix-install-libs-cgc: cd ..; $(ICP) racket/libmzgc.@LIBSFX@ "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" cd ..; $(ICP) racket/libracket.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" - cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" - cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" + cd ..; $(STRIP_LIB_DEBUG) "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" + cd ..; $(STRIP_LIB_DEBUG) "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" unix-no-install-libs-cgc: $(NOOP) @@ -424,7 +425,7 @@ unix-install-3m: unix-install-libs-3m: cd ..; $(ICP) racket/libracket3m.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" - cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" + cd ..; $(STRIP_LIB_DEBUG) "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" unix-no-install-libs-3m: $(NOOP) diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 8ad72a7af4..aea5974d24 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -450,6 +450,7 @@ INSTALL_SETUP_RACKET_FLAGS= INSTALL_LIBS_ENABLE=no-install STRIP_DEBUG=":" +STRIP_LIB_DEBUG=":" strip_debug_flags="" enable_strip_by_default=yes @@ -867,9 +868,6 @@ case "$host_os" in PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT" try_kqueue_syscall=yes - # Needed when stripping ".a"s: - strip_debug_flags=" -S" - # ".a" is typically not useful, since we always build a ".dylib": if test "${enable_libs}" == "" ; then INSTALL_LIBS_ENABLE=no-install @@ -979,10 +977,29 @@ if test "${enable_strip}" = "" ; then fi fi +try_archive_conftest() +{ + $AR $ARFLAGS conftest.a conftest.$OBJEXT > /dev/null 2>&1 +} + if test "${enable_strip}" = "yes" ; then AC_CHECK_TOOL([STRIP], [strip]) # Used to add -S flag, but not all `strip' variants support it: - STRIP_DEBUG="${STRIP}${strip_debug_flags}" + STRIP_DEBUG="${STRIP}" + if test "${INSTALL_LIBS_ENABLE}" = "install" ; then + # Can only support library stripping if something like "-S" is available: + [ msg="for strip -S" ] + AC_MSG_CHECKING($msg) + set_strip_lib=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int f() { return 0; }])], try_archive_conftest, set_strip_lib=no ) + if test conftest.a ; then + if "${STRIP_DEBUG}" -S conftest.a > /dev/null 2>&1 ; then + STRIP_LIB_DEBUG="${STRIP_DEBUG} -S" + set_strip_lib=yes + fi + fi + AC_MSG_RESULT($set_strip_lib) + fi fi ############## C flags ################ @@ -1692,6 +1709,7 @@ AC_SUBST(AR) AC_SUBST(STATIC_AR) AC_SUBST(ARFLAGS) AC_SUBST(STRIP_DEBUG) +AC_SUBST(STRIP_LIB_DEBUG) AC_SUBST(CC_FOR_BUILD) AC_SUBST(REZ) AC_SUBST(MZLINKER) From 93efe503add7e296e4662433cb0f4c1e817d98e6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 20 Sep 2015 21:06:38 -0600 Subject: [PATCH 271/381] fix misuse of comparison macro --- racket/src/racket/src/optimize.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index d8f6293cb4..c84dfff54e 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -2802,8 +2802,8 @@ static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info le = optimize_for_inline(info, app->args[i], n - 1, app, NULL, NULL, &rator_flags, context, 1, 0); if (le) return le; - if (SAME_TYPE(app->args[0], scheme_values_func) - || SAME_TYPE(app->args[0], scheme_apply_proc)) + if (SAME_OBJ(app->args[0], scheme_values_func) + || SAME_OBJ(app->args[0], scheme_apply_proc)) info->maybe_values_argument = 1; rator_apply_escapes = info->escapes; } @@ -3528,8 +3528,8 @@ static Scheme_Object *optimize_application3(Scheme_Object *o, Optimize_Info *inf rator_apply_escapes = info->escapes; } - if (SAME_TYPE(app->rator, scheme_values_func) - || SAME_TYPE(app->rator, scheme_apply_proc)) + if (SAME_OBJ(app->rator, scheme_values_func) + || SAME_OBJ(app->rator, scheme_apply_proc)) info->maybe_values_argument = 1; /* 1st arg */ From 003bca503f208099172d251c325c25c264a79724 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 20 Sep 2015 21:09:02 -0600 Subject: [PATCH 272/381] avoid compiler warnings --- racket/src/racket/src/jitinline.c | 6 ++++++ racket/src/racket/src/optimize.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index f42b64583a..0b3fb79efd 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -2777,11 +2777,17 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i ref_fx1 = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1); jit_ldxi_s(JIT_R2, JIT_R0, &((Scheme_Object *)0x0)->type); ref_fail1 = jit_bnei_i(jit_forward(), JIT_R2, string_type); + } else { + ref_fx1 = NULL; + ref_fail1 = NULL; } if (!is_str2) { ref_fx2 = jit_bmsi_ul(jit_forward(), JIT_R1, 0x1); jit_ldxi_s(JIT_V1, JIT_R1, &((Scheme_Object *)0x0)->type); ref_fail2 = jit_bnei_i(jit_forward(), JIT_V1, string_type); + } else { + ref_fx2 = NULL; + ref_fail2 = NULL; } ref_ucnofail = jit_jmpi(jit_forward()); CHECK_LIMIT(); diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index c84dfff54e..953a0c7fe8 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -5795,8 +5795,8 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i int did_set_value, checked_once, skip_depth, unused_clauses, found_escapes; int remove_last_one = 0, inline_fuel, rev_bind_order; int post_bind = !(SCHEME_LET_FLAGS(head) & (SCHEME_LET_RECURSIVE | SCHEME_LET_STAR)); - int pre_vclock, pre_aclock, pre_kclock, pre_sclock, increments_kclock; - int once_vclock, once_aclock, once_kclock, once_sclock, once_increments_kclock; + int pre_vclock, pre_aclock, pre_kclock, pre_sclock, increments_kclock = 0; + int once_vclock, once_aclock, once_kclock, once_sclock, once_increments_kclock = 0; # define pos_EARLIER(a, b) (rev_bind_order ? ((a) > (b)) : ((a) < (b))) From 35a0f0c71c6a53a0cb09520ef9de335cb06e66d4 Mon Sep 17 00:00:00 2001 From: Spencer Florence Date: Mon, 14 Sep 2015 16:24:38 -0500 Subject: [PATCH 273/381] make sure git checkout have correct perms --- racket/collects/net/git-checkout.rkt | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index 4ab3c09e9a..1e1c8a29d8 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -671,12 +671,16 @@ (when id (define (this-object-location) (object-location (hash-ref obj-ids id))) - (case (datum-intern-literal mode) - [(#"100644" #"644" - #"100755" #"755") + (define (copy-this-object perms) (copy-object tmp (this-object-location) - (build-path dest-dir fn))] + perms + (build-path dest-dir fn))) + (case (datum-intern-literal mode) + [(#"100755") #"755" + (copy-this-object #o755)] + [(#"100644" #"644") + (copy-this-object #o644)] [(#"40000" #"040000") (extract-tree id obj-ids tmp (build-path dest-dir fn))] [(#"120000") @@ -938,8 +942,8 @@ [else (call-with-input-file* (build-path (tmp-info-dir tmp) location) proc)])) -;; copy-object : tmp-info location path -> void -(define (copy-object tmp location dest-file) +;; copy-object : tmp-info location integer path -> void +(define (copy-object tmp location perms dest-file) (cond [(pair? location) (define bstr (object->bytes tmp location)) @@ -950,7 +954,10 @@ [else (copy-file (build-path (tmp-info-dir tmp) location) dest-file - #t)])) + #t)]) + (if (eq? 'windows (system-type 'os)) + (file-or-directory-permissions dest-file #o755) + (file-or-directory-permissions dest-file perms))) ;; object->bytes : tmp-info location -> bytes (define (object->bytes tmp location) From 45b635f7072b5cff884138978bb16a0559a8225a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 22 Sep 2015 09:00:55 -0500 Subject: [PATCH 274/381] don't set permissions on windows, for now (at some point hopefully we'll figure out what's the right behavior here) This is related to pull request #1060 --- racket/collects/net/git-checkout.rkt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index 1e1c8a29d8..34ac181816 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -955,9 +955,8 @@ (copy-file (build-path (tmp-info-dir tmp) location) dest-file #t)]) - (if (eq? 'windows (system-type 'os)) - (file-or-directory-permissions dest-file #o755) - (file-or-directory-permissions dest-file perms))) + (unless (equal? 'windows (system-type 'os)) + (file-or-directory-permissions dest-file perms))) ;; object->bytes : tmp-info location -> bytes (define (object->bytes tmp location) From 5a33856802f1f82260dc07ab1c3b9df3175867a9 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 22 Sep 2015 09:05:34 -0500 Subject: [PATCH 275/381] change or/c so that it takes the first ho projection whose first-order predicate accepts a value, instead of requiring that there be exactly one --- .../scribblings/reference/contracts.scrbl | 18 ++++-- .../tests/racket/contract/or-and.rkt | 22 ++++--- .../collects/racket/contract/private/orc.rkt | 64 ++++--------------- 3 files changed, 36 insertions(+), 68 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 298383b243..e75547f03f 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -182,21 +182,25 @@ If there are multiple higher-order contracts, @racket[or/c] uses them. More precisely, when an @racket[or/c] is checked, it first checks all of the @tech{flat contracts}. If none of them pass, it calls @racket[contract-first-order-passes?] with each of the -higher-order contracts. If only one returns true, @racket[or/c] uses -that contract. If none of them return true, it signals a contract -violation. If more than one returns true, it also signals a contract -violation. +higher-order contracts, taking the first one that returns +true as the contract for the value. + For example, this contract @racketblock[ (or/c (-> number? number?) (-> string? string? string?)) ] -does not accept a function like this one: @racket[(lambda args ...)] -since it cannot tell which of the two arrow contracts should be used -with the function. +accepts a function like this one: @racket[(lambda args ...)], +using the @racket[(-> number? number?)] contract on it, ignoring +the @racket[(-> string? string? string?)] contract since it came +second. If all of its arguments are @racket[list-contract?]s, then @racket[or/c] returns a @racket[list-contract?]. + +@history[#:changed "6.2.900.17" @list{Adjusted @racket[or/c] so that it + takes the first higher-order contract instead of insisting that + there be exactly one higher-order contract for a given value.}] } @defproc[(and/c [contract contract?] ...) contract?]{ diff --git a/pkgs/racket-test/tests/racket/contract/or-and.rkt b/pkgs/racket-test/tests/racket/contract/or-and.rkt index 32cecad7ad..7b41b4cc65 100644 --- a/pkgs/racket-test/tests/racket/contract/or-and.rkt +++ b/pkgs/racket-test/tests/racket/contract/or-and.rkt @@ -86,14 +86,6 @@ 1) 1) - (contract-error-test - 'contract-error-test4 - #'(contract (or/c (-> integer? integer?) (-> boolean? boolean?)) - (λ (x) x) - 'pos - 'neg) - exn:fail?) - (test/spec-passed/result 'or/c-ordering '(let ([x '()]) @@ -231,11 +223,21 @@ 'pos 'neg) (lambda (x y z) 1))) - (test/neg-blame + (test/spec-passed/result 'ho-or/c-val-first2 + '((contract (or/c (-> integer? integer?) (-> boolean? boolean?)) + (λ (x) x) + 'pos + 'neg) + 1) + 1) + + (test/spec-passed/result + 'ho-or/c-val-first3 '((contract (-> (or/c (-> number? number?) (-> number? number?)) number?) (λ (x) 1) 'pos 'neg) - (lambda (x) 1)))) + (lambda (x) 1)) + 1)) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index d1ee02c67f..de482e19d6 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -22,7 +22,7 @@ [flat-contracts '()] [args args]) (cond - [(null? args) (values ho-contracts (reverse flat-contracts))] + [(null? args) (values (reverse ho-contracts) (reverse flat-contracts))] [else (let ([arg (car args)]) (cond @@ -242,36 +242,18 @@ [else (let loop ([checks first-order-checks] [procs partial-contracts] - [contracts ho-contracts] - [candidate-proc #f] - [candidate-contract #f]) + [contracts ho-contracts]) (cond [(null? checks) - (if candidate-proc - (candidate-proc val) - (raise-blame-error blame val - '("none of the branches of the or/c matched" given: "~e") - val))] + (raise-blame-error blame val + '("none of the branches of the or/c matched" given: "~e") + val)] [((car checks) val) - (if candidate-proc - (raise-blame-error blame val - '("two of the clauses in the or/c might both match: ~s and ~s" - given: - "~e") - (contract-name candidate-contract) - (contract-name (car contracts)) - val) - (loop (cdr checks) - (cdr procs) - (cdr contracts) - (car procs) - (car contracts)))] + ((car procs) val)] [else (loop (cdr checks) (cdr procs) - (cdr contracts) - candidate-proc - candidate-contract)]))]))))) + (cdr contracts))]))]))))) (define (multi-or/c-late-neg-proj ctc) (define ho-contracts (multi-or/c-ho-ctcs ctc)) @@ -289,38 +271,18 @@ [else (let loop ([checks first-order-checks] [c-projs c-projs+blame] - [contracts ho-contracts] - [candidate-c-proj #f] - [candidate-contract #f]) + [contracts ho-contracts]) (cond [(null? checks) - (cond - [candidate-c-proj - (candidate-c-proj val neg-party)] - [else - (raise-blame-error blame val #:missing-party neg-party - '("none of the branches of the or/c matched" given: "~e") - val)])] + (raise-blame-error blame val #:missing-party neg-party + '("none of the branches of the or/c matched" given: "~e") + val)] [((car checks) val) - (if candidate-c-proj - (raise-blame-error blame val #:missing-party neg-party - '("two of the clauses in the or/c might both match: ~s and ~s" - given: - "~e") - (contract-name candidate-contract) - (contract-name (car contracts)) - val) - (loop (cdr checks) - (cdr c-projs) - (cdr contracts) - (car c-projs) - (car contracts)))] + ((car c-projs) val neg-party)] [else (loop (cdr checks) (cdr c-projs) - (cdr contracts) - candidate-c-proj - candidate-contract)]))])))) + (cdr contracts))]))])))) (define (multi-or/c-first-order ctc) (let ([flats (map flat-contract-predicate (multi-or/c-flat-ctcs ctc))] From aaf098f20388928a45cc67637e35db5f956e29fc Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 22 Sep 2015 16:36:55 -0600 Subject: [PATCH 276/381] fix potential GC problem while setting up a place channel --- racket/src/racket/gc2/mem_account.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 31e6be8845..7a3d0dd881 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -438,13 +438,17 @@ int BTC_bi_chan_mark(void *p, struct NewGC *gc) { if (gc->doing_memory_accounting) { Scheme_Place_Bi_Channel *bc = (Scheme_Place_Bi_Channel *)p; - /* Race conditions here on `mem_size', and likely double counting - when the same async channels are accessible from paired bi - channels --- but those approximations are ok for accounting. */ - if (bc->link->sendch) - account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->sendch->mem_size), 0); - if (bc->link->recvch) - account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->recvch->mem_size), 0); + /* The `link` field can be NULL if the channel is still being + set up: */ + if (bc->link) { + /* Race conditions here on `mem_size', and likely double counting + when the same async channels are accessible from paired bi + channels --- but those approximations are ok for accounting. */ + if (bc->link->sendch) + account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->sendch->mem_size), 0); + if (bc->link->recvch) + account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(bc->link->recvch->mem_size), 0); + } } return gc->mark_table[btc_redirect_bi_chan](p, gc); } From 083029fa6fc233ced243bf5077d969ec3e69b238 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 21 Sep 2015 10:35:43 -0400 Subject: [PATCH 277/381] Add pair check in unmarshalling. Closes #1070. --- racket/src/racket/src/syntax.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 2d3c57a4f4..145f3c9cb3 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -6805,6 +6805,7 @@ static Scheme_Object *unmarshal_free_id_info(Scheme_Object *p, Scheme_Unmarshal_ phase = SCHEME_CDR(p); p = SCHEME_CAR(p); + if (!SCHEME_PAIRP(p)) return_NULL; o = scheme_make_stx(SCHEME_CAR(p), NULL, NULL); p = datum_to_wraps(SCHEME_CDR(p), ut); if (!p) return_NULL; From d6ad89764ba8f4f4c9dee35fea98f7581895fb51 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 21 Sep 2015 11:07:01 -0400 Subject: [PATCH 278/381] Add a few more pair checks. --- racket/src/racket/src/syntax.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 145f3c9cb3..a7d07b3bed 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -6803,6 +6803,7 @@ static Scheme_Object *unmarshal_free_id_info(Scheme_Object *p, Scheme_Unmarshal_ { Scheme_Object *o, *phase; + if (!SCHEME_PAIRP(p)) return_NULL; phase = SCHEME_CDR(p); p = SCHEME_CAR(p); if (!SCHEME_PAIRP(p)) return_NULL; @@ -6897,6 +6898,7 @@ Scheme_Object *scope_unmarshal_content(Scheme_Object *box, Scheme_Unmarshal_Tabl if (SCHEME_BOXP(b)) { /* has `free-id=?` info */ b = SCHEME_BOX_VAL(b); + if (!SCHEME_PAIRP(b)) return_NULL; free_id = unmarshal_free_id_info(SCHEME_CDR(b), ut); if (!free_id) return_NULL; b = SCHEME_CAR(b); @@ -7212,6 +7214,8 @@ static Scheme_Object *datum_to_syntax_inner(Scheme_Object *o, if (!wraps) return_NULL; } + + if (!SCHEME_PAIRP(wraps)) return_NULL; ((Scheme_Stx *)result)->scopes = (Scheme_Scope_Table *)SCHEME_CAR(wraps); STX_ASSERT(SAME_TYPE(SCHEME_TYPE(((Scheme_Stx *)result)->scopes), scheme_scope_table_type)); ((Scheme_Stx *)result)->shifts = SCHEME_CDR(wraps); From 57b49202345477fbb231ec46314da71796d4b48f Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 23 Sep 2015 14:56:43 -0400 Subject: [PATCH 279/381] Check that serialized procedures are the right kind of procedures. Fixes http://drdr.racket-lang.org/31801/pkgs/racket-test/tests/racket/stress/fuzz.rkt --- racket/src/racket/src/marshal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index dd3ae0e21b..b0e11d66c9 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -399,6 +399,10 @@ static Scheme_Object *read_case_lambda(Scheme_Object *obj) return NULL; all_closed = 0; } + else { + if (!SAME_TYPE(SCHEME_TYPE(a), scheme_closure_type)) + return NULL; + } } if (all_closed) { From dfef5b43fc8e87c5038f13429d45e10af77e6092 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 23 Sep 2015 15:49:01 -0400 Subject: [PATCH 280/381] Add `--write` option to fuzzer. --- pkgs/racket-test/tests/racket/stress/fuzz.rkt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-test/tests/racket/stress/fuzz.rkt b/pkgs/racket-test/tests/racket/stress/fuzz.rkt index cd18869be7..fc7c706939 100644 --- a/pkgs/racket-test/tests/racket/stress/fuzz.rkt +++ b/pkgs/racket-test/tests/racket/stress/fuzz.rkt @@ -18,7 +18,7 @@ (eval (parameterize ([read-accept-compiled #t]) (with-input-from-bytes bs read))))))))) -(define (run fname seed0) +(define (run fname seed0 #:write? [out-fname? #f]) (define seed (or seed0 (+ 1 (random (expt 2 30))))) (printf "seed: ~s\nname: ~a\n" seed fname) (flush-output) @@ -26,9 +26,16 @@ (define bs (file->bytes fname)) (define len (* 8 (bytes-length bs))) (for ([i (in-range (quotient len 10000))]) (flip-bit bs (random len))) - (with-handlers ([void void]) (run-file bs))) + (with-handlers ([void void]) + (if out-fname? + (begin + (displayln (build-path (current-directory) out-fname?)) + (call-with-output-file (build-path (current-directory) out-fname?) + (lambda (o) + (write-bytes bs o)))) + (run-file bs)))) -(let ([seed0 #f] [file #f] [dir #f] [forever? #f] [global-seed #f]) +(let ([seed0 #f] [file #f] [dir #f] [forever? #f] [global-seed #f] [write? #f]) (command-line #:once-each ["--oo" "forever" (set! forever? #t)] @@ -39,13 +46,17 @@ ["-f" file* "filename to run" (set! file file*)] ["-d" dir* "dir to run" (set! dir dir*)] ["-c" "run over all collections" (set! dir (find-collects-dir))] + #:once-any + ["--write" filename "write mutated file" (begin (unless file + (error "--write requires -f")) + (set! write? filename))] #:args () (void)) (unless global-seed (set! global-seed (+ 1 (random (expt 2 30))))) (printf "Global seed: ~a\n" global-seed) (random-seed global-seed) (let loop () - (cond [file (run file seed0)] + (cond [file (run file seed0 #:write? write?)] [dir (define files (sort (for/list ([f (in-directory dir)] #:when (regexp-match #rx"\\.zo" f)) From 31549082e679abda1509ea58341a399b68e47df8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 28 Sep 2015 14:35:14 -0500 Subject: [PATCH 281/381] avoid crash when interrupting bytecode unmarshal Interrupting bytecode unmarshal for syntax objects could leave half-constructed values in a table that is intended to resolve graph structure. Clear out work towards a graph construction when interrupted. The most common symptom of half-constructed syntax objects was a crash after a Ctl-C during startup. --- racket/src/racket/src/mzmark_read.inc | 4 ++ racket/src/racket/src/mzmarksrc.c | 2 + racket/src/racket/src/read.c | 70 ++++++++++++++++++++---- racket/src/racket/src/schpriv.h | 13 +++++ racket/src/racket/src/syntax.c | 79 +++++++++++++++++++-------- 5 files changed, 133 insertions(+), 35 deletions(-) diff --git a/racket/src/racket/src/mzmark_read.inc b/racket/src/racket/src/mzmark_read.inc index 64cdf82a79..541c04d991 100644 --- a/racket/src/racket/src/mzmark_read.inc +++ b/racket/src/racket/src/mzmark_read.inc @@ -246,7 +246,9 @@ static int mark_unmarshal_tables_MARK(void *p, struct NewGC *gc) { #ifndef GC_NO_MARK_PROCEDURE_NEEDED Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcMARK2(ut->rns, gc); + gcMARK2(ut->current_rns, gc); gcMARK2(ut->multi_scope_pairs, gc); + gcMARK2(ut->current_multi_scope_pairs, gc); gcMARK2(ut->rp, gc); gcMARK2(ut->decoded, gc); # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS @@ -262,7 +264,9 @@ static int mark_unmarshal_tables_FIXUP(void *p, struct NewGC *gc) { #ifndef GC_NO_FIXUP_PROCEDURE_NEEDED Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcFIXUP2(ut->rns, gc); + gcFIXUP2(ut->current_rns, gc); gcFIXUP2(ut->multi_scope_pairs, gc); + gcFIXUP2(ut->current_multi_scope_pairs, gc); gcFIXUP2(ut->rp, gc); gcFIXUP2(ut->decoded, gc); # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 31e8fd52f1..96d438a8df 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -2326,7 +2326,9 @@ mark_unmarshal_tables { mark: Scheme_Unmarshal_Tables *ut = (Scheme_Unmarshal_Tables *)p; gcMARK2(ut->rns, gc); + gcMARK2(ut->current_rns, gc); gcMARK2(ut->multi_scope_pairs, gc); + gcMARK2(ut->current_multi_scope_pairs, gc); gcMARK2(ut->rp, gc); gcMARK2(ut->decoded, gc); size: diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index d358c322fc..3ec0ef105e 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -4397,6 +4397,34 @@ static void make_ut(CPort *port) port->ut->multi_scope_pairs = rht; } +static void prepare_current_unmarshal(Scheme_Unmarshal_Tables *ut) +{ + /* in case a previous unmarshal was interrupted: */ + ut->current_rns = NULL; + ut->current_multi_scope_pairs = NULL; +} + +static void merge_ht(Scheme_Hash_Table *f, Scheme_Hash_Table *t) +{ + int i; + for (i = f->size; i--; ) { + if (f->vals[i]) + scheme_hash_set(t, f->keys[i], f->vals[i]); + } +} + +static void complete_current_unmarshal(Scheme_Unmarshal_Tables *ut) +{ + if (ut->current_rns) { + merge_ht(ut->current_rns, ut->rns); + ut->current_rns = NULL; + } + if (ut->current_multi_scope_pairs) { + merge_ht(ut->current_multi_scope_pairs, ut->multi_scope_pairs); + ut->current_multi_scope_pairs = NULL; + } +} + /* Since read_compact_number is called often, we want it to be a cheap call in 3m, so avoid anything that allocated --- even error reporting, since we can make up a valid number. */ @@ -4563,20 +4591,33 @@ static Scheme_Object *resolve_symtab_refs(Scheme_Object *v, CPort *port) if (SCHEME_NULLP(port->symtab_refs)) return v; - v = scheme_make_pair(v, port->symtab_refs); + if (v) { + v = scheme_make_pair(v, port->symtab_refs); + + v = resolve_references(v, port->orig_port, NULL, + scheme_make_hash_table(SCHEME_hash_ptr), + scheme_make_hash_table(SCHEME_hash_ptr), + 0, 0); + + l = SCHEME_CDR(v); + } else + l = port->symtab_refs; - v = resolve_references(v, port->orig_port, NULL, - scheme_make_hash_table(SCHEME_hash_ptr), - scheme_make_hash_table(SCHEME_hash_ptr), - 0, 0); - - for (l = SCHEME_CDR(v); !SCHEME_NULLP(l); l = SCHEME_CDR(l)) { - port->symtab[SCHEME_INT_VAL(SCHEME_CAR(SCHEME_CAR(l)))] = SCHEME_CDR(SCHEME_CAR(l)); + for (; !SCHEME_NULLP(l); l = SCHEME_CDR(l)) { + if (v) + port->symtab[SCHEME_INT_VAL(SCHEME_CAR(SCHEME_CAR(l)))] = SCHEME_CDR(SCHEME_CAR(l)); + else { + /* interrupted; discard partial constructions */ + port->symtab[SCHEME_INT_VAL(SCHEME_CAR(SCHEME_CAR(l)))] = NULL; + } } port->symtab_refs = scheme_null; - - return SCHEME_CAR(v); + + if (v) + return SCHEME_CAR(v); + else + return NULL; } static Scheme_Object *read_compact(CPort *port, int use_stack); @@ -4804,6 +4845,7 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) save_ht = *port->ht; *port->ht = NULL; + prepare_current_unmarshal(port->ut); v = read_compact(port, 1); if (!SCHEME_NULLP(port->symtab_refs)) @@ -4822,6 +4864,7 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) scheme_num_read_syntax_objects++; if (!v) scheme_ill_formed_code(port); + complete_current_unmarshal(port->ut); } break; case CPT_MARSHALLED: @@ -5936,6 +5979,9 @@ Scheme_Object *scheme_load_delayed_code(int _which, Scheme_Load_Delay *_delay_in rp->pos = delay_info->shared_offsets[which - 1]; + if (delay_info->ut) + prepare_current_unmarshal(delay_info->ut); + /* Perform the read, catching escapes so we can clean up: */ savebuf = scheme_current_thread->error_buf; scheme_current_thread->error_buf = &newbuf; @@ -5954,8 +6000,10 @@ Scheme_Object *scheme_load_delayed_code(int _which, Scheme_Load_Delay *_delay_in v = resolve_symtab_refs(v, rp); delay_info->current_rp = old_rp; - if (delay_info->ut) + if (delay_info->ut) { delay_info->ut->rp = old_rp; + complete_current_unmarshal(delay_info->ut); + } if (!old_rp && !delay_info->perma_cache) { /* No one using the cache, to register it to be cleaned up */ diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 1ad35bdb3a..cfbd1fa113 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -35,6 +35,17 @@ #define HOOK_SHARED_OK /* EMPTY */ #endif +#ifdef OS_X +# define MZ_CHECK_ASSERTS +#endif + +#ifdef MZ_CHECK_ASSERTS +# include +# define MZ_ASSERT(x) assert(x) +#else +# define MZ_ASSERT(x) /* empty */ +#endif + /*========================================================================*/ /* optimization flags */ /*========================================================================*/ @@ -3377,7 +3388,9 @@ void scheme_marshal_pop_refs(Scheme_Marshal_Tables *mt, int keep); typedef struct Scheme_Unmarshal_Tables { MZTAG_IF_REQUIRED Scheme_Hash_Table *rns; + Scheme_Hash_Table *current_rns; /* in-progress unmarshal, commit to `rns` at end */ Scheme_Hash_Table *multi_scope_pairs; /* records conversions */ + Scheme_Hash_Table *current_multi_scope_pairs; /* commit to `multi_scope_pairs` at end */ struct CPort *rp; char *decoded; mzlonglong bytecode_hash; diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index a7d07b3bed..400fb17b57 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -263,16 +263,7 @@ int stx_alloc_prop_table, stx_skip_alloc_prop_table; - => clean, but inspector needs to be proagated to children - (list ...+) [interned] => armed; first inspector is to propagate */ -#ifdef OS_X -# define CHECK_STX_ASSERTS -#endif - -#ifdef CHECK_STX_ASSERTS -# include -# define STX_ASSERT(x) assert(x) -#else -# define STX_ASSERT(x) /* empty */ -#endif +#define STX_ASSERT(x) MZ_ASSERT(x) static Scheme_Object *make_vector3(Scheme_Object *a, Scheme_Object *b, Scheme_Object *c) { @@ -6531,6 +6522,37 @@ Scheme_Object *scheme_syntax_to_datum(Scheme_Object *stx, int with_scopes, #define return_NULL return NULL +Scheme_Object *scheme_hash_get_either(Scheme_Hash_Table *ht, Scheme_Hash_Table *ht2, + Scheme_Object *key) +{ + Scheme_Object *val; + val = scheme_hash_get(ht, key); + if (val) + return val; + else if (ht2) + return scheme_hash_get(ht2, key); + else + return NULL; +} + +static void ensure_current_rns(Scheme_Unmarshal_Tables *ut) +{ + Scheme_Hash_Table *rht; + if (!ut->current_rns) { + rht = scheme_make_hash_table(SCHEME_hash_ptr); + ut->current_rns = rht; + } +} + +static void ensure_current_multi_scope_pairs(Scheme_Unmarshal_Tables *ut) +{ + Scheme_Hash_Table *rht; + if (!ut->current_multi_scope_pairs) { + rht = scheme_make_hash_table(SCHEME_hash_ptr); + ut->current_multi_scope_pairs = rht; + } +} + Scheme_Scope_Set *list_to_scope_set(Scheme_Object *l, Scheme_Unmarshal_Tables *ut) { Scheme_Scope_Set *scopes = NULL; @@ -6538,7 +6560,7 @@ Scheme_Scope_Set *list_to_scope_set(Scheme_Object *l, Scheme_Unmarshal_Tables *u while (!SCHEME_NULLP(l)) { if (!SCHEME_PAIRP(l)) return_NULL; - scopes = (Scheme_Scope_Set *)scheme_hash_get(ut->rns, l); + scopes = (Scheme_Scope_Set *)scheme_hash_get_either(ut->rns, ut->current_rns, l); if (scopes) break; r = scheme_make_pair(l, r); @@ -6554,7 +6576,8 @@ Scheme_Scope_Set *list_to_scope_set(Scheme_Object *l, Scheme_Unmarshal_Tables *u if (!scope) return_NULL; scopes = scope_set_set(scopes, scope, scheme_true); - scheme_hash_set(ut->rns, l, (Scheme_Object *)scopes); + ensure_current_rns(ut); + scheme_hash_set(ut->current_rns, l, (Scheme_Object *)scopes); r = SCHEME_CDR(r); } @@ -6571,7 +6594,7 @@ static Scheme_Hash_Table *vector_to_multi_scope(Scheme_Object *mht, Scheme_Unmar if (!SCHEME_VECTORP(mht)) return_NULL; - multi_scope = (Scheme_Hash_Table *)scheme_hash_get(ut->rns, mht); + multi_scope = (Scheme_Hash_Table *)scheme_hash_get_either(ut->rns, ut->current_rns, mht); if (multi_scope) return multi_scope; multi_scope = scheme_make_hash_table(SCHEME_hash_ptr); @@ -6591,7 +6614,8 @@ static Scheme_Hash_Table *vector_to_multi_scope(Scheme_Object *mht, Scheme_Unmar len -= 1; /* A multi-scope can refer back to itself via free-id=? info: */ - scheme_hash_set(ut->rns, mht, (Scheme_Object *)multi_scope); + ensure_current_rns(ut); + scheme_hash_set(ut->current_rns, mht, (Scheme_Object *)multi_scope); for (i = 0; i < len; i += 2) { if (!SCHEME_PHASEP(SCHEME_VEC_ELS(mht)[i])) @@ -6633,9 +6657,9 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, if (!SCHEME_PAIRP(l)) return_NULL; if (!SCHEME_PAIRP(SCHEME_CAR(l))) return_NULL; - p = scheme_hash_get(ut->multi_scope_pairs, l); + p = scheme_hash_get_either(ut->multi_scope_pairs, ut->current_multi_scope_pairs, l); if (!p) { - p = scheme_hash_get(ut->multi_scope_pairs, SCHEME_CAR(l)); + p = scheme_hash_get_either(ut->multi_scope_pairs, ut->current_multi_scope_pairs, SCHEME_CAR(l)); if (p) { p = scheme_make_pair(p, scheme_null); } else { @@ -6645,11 +6669,13 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, if (!SCHEME_PHASE_SHIFTP(SCHEME_CDR(SCHEME_CAR(l)))) return_NULL; p = scheme_make_pair((Scheme_Object *)multi_scope, SCHEME_CDR(SCHEME_CAR(l))); - scheme_hash_set(ut->multi_scope_pairs, SCHEME_CAR(l), p); + ensure_current_multi_scope_pairs(ut); + scheme_hash_set(ut->current_multi_scope_pairs, SCHEME_CAR(l), p); } else return_NULL; } - scheme_hash_set(ut->multi_scope_pairs, SCHEME_CAR(l), p); + ensure_current_multi_scope_pairs(ut); + scheme_hash_set(ut->current_multi_scope_pairs, SCHEME_CAR(l), p); p = scheme_make_pair(p, scheme_null); stop = 0; } else @@ -6663,8 +6689,10 @@ Scheme_Object *unmarshal_multi_scopes(Scheme_Object *multi_scopes, if (stop) break; - else - scheme_hash_set(ut->multi_scope_pairs, l, p); + else { + ensure_current_multi_scope_pairs(ut); + scheme_hash_set(ut->current_multi_scope_pairs, l, p); + } } if (SCHEME_FALLBACKP(mm_l)) { @@ -6694,7 +6722,7 @@ static Scheme_Object *datum_to_wraps(Scheme_Object *w, Scheme_Scope_Set *scopes; Scheme_Object *l; - l = scheme_hash_get(ut->rns, w); + l = scheme_hash_get_either(ut->rns, ut->current_rns, w); if (l) { if (!SCHEME_PAIRP(l) || !SAME_TYPE(SCHEME_TYPE(SCHEME_CAR(l)), scheme_scope_table_type)) @@ -6719,7 +6747,8 @@ static Scheme_Object *datum_to_wraps(Scheme_Object *w, st->multi_scopes = l; l = scheme_make_pair((Scheme_Object *)st, SCHEME_VEC_ELS(w)[0]); - scheme_hash_set(ut->rns, w, l); + ensure_current_rns(ut); + scheme_hash_set(ut->current_rns, w, l); return l; } @@ -6828,7 +6857,7 @@ Scheme_Object *scope_unmarshal_content(Scheme_Object *box, Scheme_Unmarshal_Tabl if (SAME_OBJ(box, root_scope)) return root_scope; - r = scheme_hash_get(ut->rns, box); + r = scheme_hash_get_either(ut->rns, ut->current_rns, box); if (r) return r; @@ -6848,7 +6877,9 @@ Scheme_Object *scope_unmarshal_content(Scheme_Object *box, Scheme_Unmarshal_Tabl c = SCHEME_CDR(c); } else m = scheme_new_scope(SCHEME_STX_MACRO_SCOPE); - scheme_hash_set(ut->rns, box, m); + + ensure_current_rns(ut); + scheme_hash_set(ut->current_rns, box, m); /* Since we've created the scope before unmarshaling its content, cycles among scopes are ok. */ From 6e8060999837e9234d10883a02854428f934d4e0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 30 Sep 2015 06:57:32 -0600 Subject: [PATCH 282/381] macro expander: fix over-eager pruning of use-site scopes The bug could cause #lang racket/base (define x 'outer) (define-syntax-rule (def-and-use-m given-x) (begin (define-syntax-rule (m) (let () (define given-x 'inner) x)) (m))) (def-and-use-m x) to produce 'inner when it should produce 'outer. Thanks to Brian Mastenbrook for pointing the problem and providing examples. --- pkgs/racket-test-core/tests/racket/macro.rktl | 108 ++++++++++++++++++ pkgs/racket-test-core/tests/racket/stx.rktl | 1 + racket/src/racket/src/compile.c | 20 +--- racket/src/racket/src/module.c | 6 +- racket/src/racket/src/syntax.c | 21 ++-- 5 files changed, 124 insertions(+), 32 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/macro.rktl b/pkgs/racket-test-core/tests/racket/macro.rktl index dc0bc57b63..fa156577cb 100644 --- a/pkgs/racket-test-core/tests/racket/macro.rktl +++ b/pkgs/racket-test-core/tests/racket/macro.rktl @@ -1445,6 +1445,114 @@ (eval-syntax #'a) (eval-syntax (expand-syntax #'b)))]))) +;; ---------------------------------------- +;; Check that use-site scopes are not pruned too eagerly +;; (based on examples from Brian Mastenbrook) + +(module should-be-inner-1 racket/base + (define x 'outer) + + (define-syntax-rule (def-m m given-x) + (define-syntax-rule (m d) + (begin + (define given-x 'inner) + (define d x)))) + + (def-m m x) + (m d) + (provide d)) + +(test 'inner dynamic-require ''should-be-inner-1 'd) + +(module should-be-inner-2 racket/base + (define x 'outer) + + (define d + (let () + (define-syntax-rule (def-m m given-x) + (define-syntax-rule (m) + (begin + (define given-x 'inner) + x))) + + (def-m m x) + (m))) + + (provide d)) + +(test 'inner dynamic-require ''should-be-inner-2 'd) + +(module should-be-outer-1 racket/base + (define x 'outer) + + (define-syntax-rule (def-m m given-x) + (define-syntax-rule (m d) + (define d + (let () + (define given-x 'inner) + x)))) + + (def-m m x) + (m d) + (provide d)) + +(test 'outer dynamic-require ''should-be-outer-1 'd) + +(module should-be-outer-2 racket/base + (define x 'outer) + + (define-syntax-rule (def-m m given-x) + (define-syntax-rule (m) + (begin + (define given-x 'inner) + x))) + + (define d + (let () + (def-m m x) + (m))) + + (provide d)) + +(test 'outer dynamic-require ''should-be-outer-2 'd) + +(module should-be-outer-3 racket/base + (define x 'outer) + + (define-syntax-rule (def-m m given-x) + (define-syntax-rule (m) + (begin + (define given-x 'inner) + x))) + + (def-m m x) + (define d + (let () + (m))) + + (provide d)) + +(test 'outer dynamic-require ''should-be-outer-3 'd) + +(module should-be-outer-4 racket/base + (define x 'outer) + + (define d + (let () + (define-syntax-rule (def-m m given-x) + (define-syntax-rule (m) + (begin + (define given-x 'inner) + x))) + + (def-m m x) + (let () + (m)))) + + (provide d)) + +(test 'outer dynamic-require ''should-be-outer-4 'd) + ;; ---------------------------------------- (report-errs) diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 93bef70763..f434d05209 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -1408,6 +1408,7 @@ (eval '(require 'mm)) (eval '(current-namespace (module->namespace ''mm))) + (test '(1 2) eval '(list a b)) (eval '(define$ c 7)) (test '(1 2 7) eval '(list a b c)) (eval '(define$ d 8)) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 47a046d2e6..0787464bbd 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -3407,17 +3407,9 @@ quote_syntax_syntax(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Compi /* Remove scopes for all enclosing local binding contexts. */ for (frame = env; frame; frame = frame->next) { - if (frame->flags & (SCHEME_TOPLEVEL_FRAME | SCHEME_MODULE_FRAME | SCHEME_MODULE_BEGIN_FRAME)) - stx = scheme_stx_adjust_module_use_site_context(stx, - env->genv->stx_context, - SCHEME_STX_REMOVE); - else if (frame->scopes) { - if (frame->flags & SCHEME_KEEP_SCOPES_FRAME) - stx = scheme_stx_adjust_frame_use_site_scopes(stx, frame->scopes, - scheme_env_phase(frame->genv), SCHEME_STX_REMOVE); - else - stx = scheme_stx_adjust_frame_scopes(stx, frame->scopes, - scheme_env_phase(frame->genv), SCHEME_STX_REMOVE); + if ((frame->scopes) && !(frame->flags & SCHEME_KEEP_SCOPES_FRAME)) { + stx = scheme_stx_adjust_frame_scopes(stx, frame->scopes, + scheme_env_phase(frame->genv), SCHEME_STX_REMOVE); } } @@ -3482,8 +3474,6 @@ do_define_syntaxes_syntax(Scheme_Object *form, Scheme_Comp_Env *env, scheme_define_parse(form, &names, &code, 1, env, 0); - code = scheme_revert_use_site_scopes(code, env); - scheme_prepare_exp_env(env->genv); scheme_prepare_compile_env(env->genv->exp_env); @@ -3532,8 +3522,6 @@ define_syntaxes_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Ex scheme_define_parse(form, &names, &code, 1, env, 0); - code = scheme_revert_use_site_scopes(code, env); - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); scheme_prepare_exp_env(env->genv); @@ -6099,8 +6087,6 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, "extra data after expression"); } expr = SCHEME_STX_CAR(expr); - if (!is_val) - expr = scheme_revert_use_site_scopes(expr, env); scheme_add_local_syntax(cnt, new_env); diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 41c8e0177d..40ab74d22c 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -9009,8 +9009,6 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ int for_stx; int max_let_depth; - e = revert_use_site_scopes_via_context(e, rn_set, phase); - for_stx = scheme_stx_free_eq_x(scheme_begin_for_syntax_stx, fst, phase); SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); @@ -9039,7 +9037,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ eenv = scheme_new_comp_env(env->genv->exp_env, env->insp, frame_scopes, - 0); + SCHEME_KEEP_SCOPES_FRAME); if (!for_stx) scheme_frame_captures_lifts(eenv, NULL, NULL, scheme_false, scheme_false, req_data, scheme_false, scheme_false); @@ -9207,7 +9205,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ m = SCHEME_STX_CDR(e); m = SCHEME_STX_CAR(m); m = scheme_make_pair(fst, - scheme_make_pair(m, scheme_make_pair(code, scheme_null))); + scheme_make_pair(orig_names, scheme_make_pair(code, scheme_null))); } e = scheme_datum_to_syntax(m, e, e, 0, 2); } else diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 400fb17b57..495c9c8a49 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -4118,7 +4118,7 @@ Scheme_Object *scheme_make_module_context(Scheme_Object *insp, Scheme_Object *shift_or_shifts, Scheme_Object *debug_name) { - Scheme_Object *vec; + Scheme_Object *vec, *bx; Scheme_Object *body_scopes; Scheme_Object *intro_multi_scope; @@ -4161,7 +4161,8 @@ Scheme_Object *scheme_make_module_context(Scheme_Object *insp, SCHEME_VEC_ELS(vec)[2] = insp; SCHEME_VEC_ELS(vec)[3] = shift_or_shifts; SCHEME_VEC_ELS(vec)[4] = intro_multi_scope; - SCHEME_VEC_ELS(vec)[5] = (Scheme_Object *)empty_scope_set; + bx = scheme_box((Scheme_Object *)empty_scope_set); + SCHEME_VEC_ELS(vec)[5] = bx; return vec; } @@ -4202,20 +4203,20 @@ Scheme_Object *scheme_module_context_frame_scopes(Scheme_Object *mc, Scheme_Obje void scheme_module_context_add_use_site_scope(Scheme_Object *mc, Scheme_Object *use_site_scope) { - Scheme_Scope_Set *use_site_scopes = (Scheme_Scope_Set *)SCHEME_VEC_ELS(mc)[5]; + Scheme_Scope_Set *use_site_scopes = (Scheme_Scope_Set *)SCHEME_BOX_VAL(SCHEME_VEC_ELS(mc)[5]); STX_ASSERT(SCHEME_SCOPEP(use_site_scope)); use_site_scopes = scope_set_set(use_site_scopes, use_site_scope, scheme_true); - SCHEME_VEC_ELS(mc)[5] = (Scheme_Object *)use_site_scopes; + SCHEME_BOX_VAL(SCHEME_VEC_ELS(mc)[5]) = (Scheme_Object *)use_site_scopes; } Scheme_Object *scheme_module_context_use_site_frame_scopes(Scheme_Object *mc) { Scheme_Scope_Set *use_site_scopes; - use_site_scopes = (Scheme_Scope_Set *)SCHEME_VEC_ELS(mc)[5]; + use_site_scopes = (Scheme_Scope_Set *)SCHEME_BOX_VAL(SCHEME_VEC_ELS(mc)[5]); if (SAME_OBJ(use_site_scopes, empty_scope_set)) return NULL; else @@ -4247,10 +4248,7 @@ Scheme_Object *scheme_module_context_at_phase(Scheme_Object *mc, Scheme_Object * SCHEME_VEC_ELS(vec)[2] = SCHEME_VEC_ELS(mc)[2]; SCHEME_VEC_ELS(vec)[3] = SCHEME_VEC_ELS(mc)[3]; SCHEME_VEC_ELS(vec)[4] = SCHEME_VEC_ELS(mc)[4]; - /* Any use-site scope from the from another phase don't apply here. This - set only matters for module contexts that are attached to environments, - anyway: */ - SCHEME_VEC_ELS(vec)[5] = (Scheme_Object *)empty_scope_set; + SCHEME_VEC_ELS(vec)[5] = SCHEME_VEC_ELS(mc)[5]; return vec; } @@ -4332,7 +4330,7 @@ Scheme_Object *scheme_stx_unintroduce_from_module_context(Scheme_Object *stx, Sc Scheme_Object *scheme_stx_adjust_module_use_site_context(Scheme_Object *stx, Scheme_Object *mc, int mode) { - Scheme_Scope_Set *scopes = (Scheme_Scope_Set *)SCHEME_VEC_ELS(mc)[5]; + Scheme_Scope_Set *scopes = (Scheme_Scope_Set *)SCHEME_BOX_VAL(SCHEME_VEC_ELS(mc)[5]); return scheme_stx_adjust_scopes(stx, scopes, SCHEME_VEC_ELS(mc)[1], mode); } @@ -4706,7 +4704,8 @@ Scheme_Object *scheme_stx_to_module_context(Scheme_Object *_stx) SCHEME_VEC_ELS(vec)[2] = scheme_false; /* not sure this is right */ SCHEME_VEC_ELS(vec)[3] = shifts; SCHEME_VEC_ELS(vec)[4] = intro_multi_scope; - SCHEME_VEC_ELS(vec)[5] = (Scheme_Object *)empty_scope_set; + a = scheme_box((Scheme_Object *)empty_scope_set); + SCHEME_VEC_ELS(vec)[5] = a; return vec; } From 7abe38e7631bf0f6bd2d4f44ca1a6ea95a00e923 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 30 Sep 2015 11:32:16 -0600 Subject: [PATCH 283/381] adjust namespace-relative treatment of compiled `require` Removing all original module context doesn't work, because it doesn't distinguish between fragments of syntax that had the "inside-edge" scope without the "outside-edge" scope. Record the presence of the outside-edge scope by using the root scope, and convert the root scope to the current namespace's outside-edge scope on evaluation. --- pkgs/racket-test-core/tests/racket/stx.rktl | 16 +++ racket/src/racket/src/module.c | 4 +- racket/src/racket/src/schpriv.h | 3 + racket/src/racket/src/syntax.c | 105 ++++++++++++++++++++ 4 files changed, 126 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index f434d05209..5cce96d9e6 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -2057,6 +2057,7 @@ ;; In `ns1`, `cons` refers to `add1` ;; In `ns2`, `cons` refers to `cons` (define cons-id/ns1 (eval '(quote-syntax cons) ns1)) + (test add1 eval cons-id/ns1 ns1) (test add1 eval cons-id/ns1 ns2) (eval `(define ,cons-id/ns1 1) ns2) (test 1 eval cons-id/ns1 ns2) @@ -2190,4 +2191,19 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(parameterize ([current-namespace (make-base-namespace)]) + (eval '(require (for-syntax racket/base))) + (eval + '(define-syntax (m stx) + (define x (car (generate-temporaries '(1)))) + (syntax-case stx () + [(_ lib name) + #`(begin (require (only-in lib [name #,x])) + (define-syntax name + (make-rename-transformer (quote-syntax #,x))) + name)]))) + (eval '(m racket/base values))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (report-errs) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 40ab74d22c..c0a2ee8718 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -12513,7 +12513,7 @@ do_require_execute(Scheme_Env *env, Scheme_Object *form) Scheme_Object *modidx; /* Use the current top-level context: */ - form = scheme_stx_add_module_context(form, env->stx_context); + form = scheme_stx_from_generic_to_module_context(form, env->stx_context); /* Check for collisions again, in case there's a difference between compile and run times: */ @@ -12559,7 +12559,7 @@ static Scheme_Object *do_require(Scheme_Object *form, Scheme_Comp_Env *env, if (rec && rec[drec].comp) { /* Remove all context specific to the compile-time environment: */ - form = scheme_stx_remove_module_context(form, env->genv->stx_context); + form = scheme_stx_from_module_context_to_generic(form, env->genv->stx_context); /* Dummy lets us access a top-level environment: */ dummy = scheme_make_environment_dummy(env); diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index cfbd1fa113..3298dc2041 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1223,6 +1223,9 @@ Scheme_Object *scheme_stx_unintroduce_from_module_context(Scheme_Object *stx, Sc Scheme_Object *scheme_stx_push_module_context(Scheme_Object *stx, Scheme_Object *mc); Scheme_Object *scheme_stx_push_introduce_module_context(Scheme_Object *stx, Scheme_Object *mc); +Scheme_Object *scheme_stx_from_module_context_to_generic(Scheme_Object *stx, Scheme_Object *mc); +Scheme_Object *scheme_stx_from_generic_to_module_context(Scheme_Object *stx, Scheme_Object *mc); + Scheme_Object *scheme_module_context_to_stx(Scheme_Object *mc, Scheme_Object *orig_src); Scheme_Object *scheme_stx_to_module_context(Scheme_Object *stx); diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index 495c9c8a49..dc318d5a4d 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -1199,6 +1199,9 @@ static Scheme_Object *stx_adjust_scopes(Scheme_Object *o, Scheme_Scope_Set *scop Scheme_Object *key, *val; intptr_t i; + STX_ASSERT(SCHEME_STXP(o)); + STX_ASSERT(SCHEME_SCOPE_SETP(scopes)); + i = scope_set_next(scopes, -1); while (i != -1) { scope_set_index(scopes, i, &key, &val); @@ -4335,6 +4338,108 @@ Scheme_Object *scheme_stx_adjust_module_use_site_context(Scheme_Object *stx, Sch return scheme_stx_adjust_scopes(stx, scopes, SCHEME_VEC_ELS(mc)[1], mode); } +#ifdef DO_STACK_CHECK +static Scheme_Object *replace_scopes(Scheme_Object *stx, Scheme_Object *remove_scopes, + Scheme_Object *add_scopes, Scheme_Object *phase); + +static Scheme_Object *replace_scopes_k(void) +{ + Scheme_Thread *p = scheme_current_thread; + Scheme_Object *stx = (Scheme_Object *)p->ku.k.p1; + Scheme_Object *remove_scopes = (Scheme_Object *)p->ku.k.p2; + Scheme_Object *add_scopes = (Scheme_Object *)p->ku.k.p3; + Scheme_Object *phase = (Scheme_Object *)p->ku.k.p4; + + p->ku.k.p1 = NULL; + p->ku.k.p2 = NULL; + p->ku.k.p3 = NULL; + p->ku.k.p4 = NULL; + + return replace_scopes(stx, remove_scopes, add_scopes, phase); +} +#endif + +static Scheme_Object *replace_scopes(Scheme_Object *stx, Scheme_Object *remove_scopes, + Scheme_Object *add_scopes, Scheme_Object *phase) +{ + Scheme_Object *sym, *sym2, *content; + +#ifdef DO_STACK_CHECK + { +# include "mzstkchk.h" + { + Scheme_Thread *p = scheme_current_thread; + + p->ku.k.p1 = (void *)stx; + p->ku.k.p2 = (void *)remove_scopes; + p->ku.k.p3 = (void *)add_scopes; + p->ku.k.p4 = (void *)phase; + + return scheme_handle_stack_overflow(replace_scopes_k); + } + } +#endif + + if (SCHEME_STXP(stx)) { + int mutate = 0; + + scheme_stx_content(stx); + if (HAS_SUBSTX(SCHEME_STX_VAL(stx))) { + content = replace_scopes(SCHEME_STX_VAL(stx), remove_scopes, add_scopes, phase); + sym = scheme_datum_to_syntax(scheme_false, scheme_false, stx, 0, 0); + } else { + sym = stx; + content = SCHEME_STX_VAL(stx); + } + + if (SCHEME_SCOPEP(remove_scopes) || SCHEME_MULTI_SCOPEP(remove_scopes)) + sym2 = stx_adjust_scope(sym, remove_scopes, phase, SCHEME_STX_REMOVE, &mutate); + else + sym2 = stx_adjust_scopes(sym, (Scheme_Scope_Set *)remove_scopes, phase, SCHEME_STX_REMOVE, &mutate); + + if (!SAME_OBJ(sym, sym2) || !SAME_OBJ(content, SCHEME_STX_VAL(stx))) { + if (SCHEME_SCOPEP(add_scopes) || SCHEME_MULTI_SCOPEP(add_scopes)) + sym2 = stx_adjust_scope(sym2, add_scopes, phase, SCHEME_STX_ADD, &mutate); + else + sym2 = stx_adjust_scopes(sym2, (Scheme_Scope_Set *)add_scopes, phase, SCHEME_STX_ADD, &mutate); + return scheme_datum_to_syntax(content, stx, sym2, 0, 2); + } else + return stx; + } else if (SCHEME_NULLP(stx)) { + return stx; + } else if (SCHEME_PAIRP(stx)) { + sym = replace_scopes(SCHEME_CAR(stx), remove_scopes, add_scopes, phase); + sym2 = replace_scopes(SCHEME_CDR(stx), remove_scopes, add_scopes, phase); + if (SAME_OBJ(sym, SCHEME_CAR(stx)) && SAME_OBJ(sym2, SCHEME_CDR(stx))) + return stx; + else + return scheme_make_pair(sym, sym2); + } else { + scheme_signal_error("internal error: unsupported form for replace_scopes()"); + return NULL; + } +} + +Scheme_Object *scheme_stx_from_module_context_to_generic(Scheme_Object *stx, Scheme_Object *mc) +{ + /* remove the introduction scope, which should be everywhere, and + map the other scopes to the root scope */ + Scheme_Object *scopes; + stx = scheme_stx_remove_scope(stx, SCHEME_VEC_ELS(mc)[4], SCHEME_VEC_ELS(mc)[1]); + scopes = (Scheme_Object *)scheme_module_context_scopes(mc); + return replace_scopes(stx, scopes, root_scope, SCHEME_VEC_ELS(mc)[1]); +} + +Scheme_Object *scheme_stx_from_generic_to_module_context(Scheme_Object *stx, Scheme_Object *mc) +{ + /* map the root scope to the body scope, and add the introduction + scope everywhere */ + Scheme_Object *scopes; + scopes = (Scheme_Object *)scheme_module_context_scopes(mc); + stx = replace_scopes(stx, root_scope, scopes, SCHEME_VEC_ELS(mc)[1]); + return scheme_stx_introduce_to_module_context(stx, mc); +} + void scheme_extend_module_context(Scheme_Object *mc, /* (vector ...) */ Scheme_Object *ctx, /* binding context (as stx) or NULL */ Scheme_Object *modidx, /* actual source module */ From 7671c15b1718c018530605e613e5fc8bdaf362ed Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 1 Oct 2015 21:23:25 -0600 Subject: [PATCH 284/381] more GC callback shapes to support Mac OS X 10.11 --- racket/src/racket/src/thread.c | 68 +++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 48fe553724..e18a17a96d 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -8719,10 +8719,26 @@ void scheme_remove_gc_callback(Scheme_Object *key) # define mzOSAPI /* empty */ #endif +#ifdef SIXTY_FOUR_BIT_INTEGERS +typedef double mzCGFloat; +#else +typedef float mzCGFloat; +#endif + +typedef struct { + struct { mzCGFloat x, y; } origin; + struct { mzCGFloat w, h; } size; +} mzNSRect; + +typedef void (*gccb_Int_to_Void)(int); typedef void (*gccb_Ptr_Ptr_Ptr_Int_to_Void)(void*, void*, void*, int); typedef void (*gccb_Ptr_Ptr_Ptr_to_Void)(void*, void*, void*); +typedef void* (*gccb_Ptr_Ptr_to_Ptr)(void*, void*); +typedef void (*gccb_Ptr_Ptr_to_Void)(void*, void*); typedef void (*gccb_Ptr_Ptr_Float_to_Void)(void*, void*, float); typedef void (*gccb_Ptr_Ptr_Double_to_Void)(void*, void*, double); +typedef void (*gccb_Float_Float_Float_Float_to_Void)(float, float, float, float); +typedef void (*gccb_Ptr_Ptr_NSRect_to_Void)(void*, void*, mzNSRect); typedef void (*gccb_Ptr_Ptr_Ptr_Nine_Ints)(void*,void*,void*,int,int,int,int,int,int,int,int,int); typedef void (mzOSAPI *gccb_OSapi_Ptr_Int_to_Void)(void*, int); typedef void (mzOSAPI *gccb_OSapi_Ptr_Ptr_to_Void)(void*, void*); @@ -8738,6 +8754,7 @@ static void run_gc_callbacks(int pre) { Scheme_GC_Pre_Post_Callback_Desc *prev = NULL, *desc; Scheme_Object *acts, *act, *protocol; + void *save = NULL; int j; desc = gc_prepost_callback_descs; @@ -8759,7 +8776,15 @@ static void run_gc_callbacks(int pre) protocol = SCHEME_VEC_ELS(act)[0]; /* The set of suported protocols is arbitary, based on what we've needed so far. */ - if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr_ptr_int->void")) { + if (!strcmp(SCHEME_SYM_VAL(protocol), "int->void")) { + gccb_Int_to_Void proc; + int i; + + proc = (gccb_Int_to_Void)scheme_extract_pointer(SCHEME_VEC_ELS(act)[1]); + i = SCHEME_INT_VAL(SCHEME_VEC_ELS(act)[2]); + + proc(i); + } else if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr_ptr_int->void")) { gccb_Ptr_Ptr_Ptr_Int_to_Void proc; void *a, *b, *c; int i; @@ -8771,6 +8796,25 @@ static void run_gc_callbacks(int pre) i = SCHEME_INT_VAL(SCHEME_VEC_ELS(act)[5]); proc(a, b, c, i); + } else if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr->save")) { + gccb_Ptr_Ptr_to_Ptr proc; + void *a, *b; + + proc = (gccb_Ptr_Ptr_to_Ptr)scheme_extract_pointer(SCHEME_VEC_ELS(act)[1]); + a = scheme_extract_pointer(SCHEME_VEC_ELS(act)[2]); + b = scheme_extract_pointer(SCHEME_VEC_ELS(act)[3]); + + save = proc(a, b); + } else if (!strcmp(SCHEME_SYM_VAL(protocol), "save!_ptr->void")) { + if (save) { + gccb_Ptr_Ptr_to_Void proc; + void *b; + + proc = (gccb_Ptr_Ptr_to_Void)scheme_extract_pointer(SCHEME_VEC_ELS(act)[1]); + b = scheme_extract_pointer(SCHEME_VEC_ELS(act)[2]); + + proc(save, b); + } } else if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr_ptr->void")) { gccb_Ptr_Ptr_Ptr_to_Void proc; void *a, *b, *c; @@ -8803,6 +8847,28 @@ static void run_gc_callbacks(int pre) d = SCHEME_DBL_VAL(SCHEME_VEC_ELS(act)[4]); proc(a, b, d); + } else if (!strcmp(SCHEME_SYM_VAL(protocol), "float_float_float_float->void")) { + gccb_Float_Float_Float_Float_to_Void proc; + double d1, d2, d3, d4; + + proc = (gccb_Float_Float_Float_Float_to_Void)scheme_extract_pointer(SCHEME_VEC_ELS(act)[1]); + d1 = SCHEME_DBL_VAL(SCHEME_VEC_ELS(act)[2]); + d2 = SCHEME_DBL_VAL(SCHEME_VEC_ELS(act)[3]); + d3 = SCHEME_DBL_VAL(SCHEME_VEC_ELS(act)[4]); + d4 = SCHEME_DBL_VAL(SCHEME_VEC_ELS(act)[5]); + + proc(d1, d2, d3, d4); + } else if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr_NSRect->void")) { + gccb_Ptr_Ptr_NSRect_to_Void proc; + void *a, *b; + mzNSRect r; + + proc = (gccb_Ptr_Ptr_NSRect_to_Void)scheme_extract_pointer(SCHEME_VEC_ELS(act)[1]); + a = scheme_extract_pointer(SCHEME_VEC_ELS(act)[2]); + b = scheme_extract_pointer(SCHEME_VEC_ELS(act)[3]); + r = *(mzNSRect *)SCHEME_PTR_VAL(SCHEME_VEC_ELS(act)[4]); + + proc(a, b, r); } else if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void")) { gccb_Ptr_Ptr_Ptr_Nine_Ints proc; void *a, *b, *c; From acac7092c515389b618e69b1342632b790c91794 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 1 Oct 2015 21:30:46 -0600 Subject: [PATCH 285/381] doc tweak --- pkgs/racket-doc/scribblings/foreign/define.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/foreign/define.scrbl b/pkgs/racket-doc/scribblings/foreign/define.scrbl index a56c1f073c..c1be430dd2 100644 --- a/pkgs/racket-doc/scribblings/foreign/define.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/define.scrbl @@ -23,8 +23,8 @@ the library produced by @racket[ffi-lib-expr]. The syntax of (code:line #:fail fail-expr)])] A @racket[define-id] form binds @racket[id] by extracting a binding -with the name @racket[c-id] from the library produced by -@racket[ffi-lib-expr], where @racket[c-id] defaults to @racket[id]. +with the name @racket[_c-id] from the library produced by +@racket[ffi-lib-expr], where @racket[_c-id] defaults to @racket[_id]. The other options support further wrapping and configuration: @itemize[ From 8c51d50cd27770d9e2e88b34f22c7c9d7fb220a5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 1 Oct 2015 22:04:24 -0600 Subject: [PATCH 286/381] raco pkg: improve Git repo-download caching Drop the path and branch from a URL that references a Git repository, so that a single download is used for multiple packages in the same repo. --- racket/collects/pkg/private/download.rkt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/racket/collects/pkg/private/download.rkt b/racket/collects/pkg/private/download.rkt index 8199c822ff..47fc8e401b 100644 --- a/racket/collects/pkg/private/download.rkt +++ b/racket/collects/pkg/private/download.rkt @@ -27,12 +27,12 @@ rest] [_ rp]))) -(define (do-cache-file file url checksum use-cache? download-printf download!) +(define (do-cache-file file url key checksum use-cache? download-printf download!) (cond [(and use-cache? checksum) (cache-file file #:exists-ok? #t - (list (url->string url) checksum) + (list key checksum) (get-download-cache-dir) download! #:log-error-string (lambda (s) (log-pkg-error s)) @@ -76,7 +76,8 @@ " server response: ~a") (url->string url) (read-line (open-input-string reply-s)))))))))) - (do-cache-file file url checksum use-cache? download-printf download!))) + (do-cache-file file url (url->string url) checksum + use-cache? download-printf download!))) (define (clean-cache pkg-url checksum) (when pkg-url @@ -116,7 +117,8 @@ #:exists-ok? #t (directory-list)))) - (do-cache-file tmp.tgz url checksum use-cache? download-printf download!) + (do-cache-file tmp.tgz url (vector transport host port repo) checksum + use-cache? download-printf download!) (unless unpacked? (untgz tmp.tgz #:dest dest-dir)) From ed07a5e1762e5fffef13346bc442973e808233eb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Oct 2015 05:50:06 -0600 Subject: [PATCH 287/381] fixup --- racket/src/racket/src/thread.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index e18a17a96d..b7384d19b4 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -8719,17 +8719,6 @@ void scheme_remove_gc_callback(Scheme_Object *key) # define mzOSAPI /* empty */ #endif -#ifdef SIXTY_FOUR_BIT_INTEGERS -typedef double mzCGFloat; -#else -typedef float mzCGFloat; -#endif - -typedef struct { - struct { mzCGFloat x, y; } origin; - struct { mzCGFloat w, h; } size; -} mzNSRect; - typedef void (*gccb_Int_to_Void)(int); typedef void (*gccb_Ptr_Ptr_Ptr_Int_to_Void)(void*, void*, void*, int); typedef void (*gccb_Ptr_Ptr_Ptr_to_Void)(void*, void*, void*); @@ -8738,7 +8727,6 @@ typedef void (*gccb_Ptr_Ptr_to_Void)(void*, void*); typedef void (*gccb_Ptr_Ptr_Float_to_Void)(void*, void*, float); typedef void (*gccb_Ptr_Ptr_Double_to_Void)(void*, void*, double); typedef void (*gccb_Float_Float_Float_Float_to_Void)(float, float, float, float); -typedef void (*gccb_Ptr_Ptr_NSRect_to_Void)(void*, void*, mzNSRect); typedef void (*gccb_Ptr_Ptr_Ptr_Nine_Ints)(void*,void*,void*,int,int,int,int,int,int,int,int,int); typedef void (mzOSAPI *gccb_OSapi_Ptr_Int_to_Void)(void*, int); typedef void (mzOSAPI *gccb_OSapi_Ptr_Ptr_to_Void)(void*, void*); @@ -8858,17 +8846,6 @@ static void run_gc_callbacks(int pre) d4 = SCHEME_DBL_VAL(SCHEME_VEC_ELS(act)[5]); proc(d1, d2, d3, d4); - } else if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr_NSRect->void")) { - gccb_Ptr_Ptr_NSRect_to_Void proc; - void *a, *b; - mzNSRect r; - - proc = (gccb_Ptr_Ptr_NSRect_to_Void)scheme_extract_pointer(SCHEME_VEC_ELS(act)[1]); - a = scheme_extract_pointer(SCHEME_VEC_ELS(act)[2]); - b = scheme_extract_pointer(SCHEME_VEC_ELS(act)[3]); - r = *(mzNSRect *)SCHEME_PTR_VAL(SCHEME_VEC_ELS(act)[4]); - - proc(a, b, r); } else if (!strcmp(SCHEME_SYM_VAL(protocol), "ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void")) { gccb_Ptr_Ptr_Ptr_Nine_Ints proc; void *a, *b, *c; From 4caaf3e8b3158572bfe9dd80fed633db0a4fdcfe Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Oct 2015 08:31:10 -0600 Subject: [PATCH 288/381] Use "https://" instead of "git://" for GitHub download I originally chose "git://" because I thought "https://" from GitHub didn't support `--depth 1`, but that does not seem to be the case. --- racket/collects/pkg/private/repo-path.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/pkg/private/repo-path.rkt b/racket/collects/pkg/private/repo-path.rkt index a6589192c1..307c355ae0 100644 --- a/racket/collects/pkg/private/repo-path.rkt +++ b/racket/collects/pkg/private/repo-path.rkt @@ -49,7 +49,7 @@ (eq? type 'github)) (match (split-github-url pkg-url) [(list* user repo branch path) - (values 'git "github.com" #f (~a user "/" repo) branch path)]) + (values 'https "github.com" #f (~a user "/" repo) branch path)]) (split-git-url pkg-url))) (define (enclosing-path-for-repo url-str in-repo-dir) From 42cf80815dbc17672463d490f3f6b4bef52e0fc2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Oct 2015 09:05:34 -0600 Subject: [PATCH 289/381] net/git-checkout: fix checkout of symlinks --- racket/collects/net/git-checkout.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index 34ac181816..d20db03a2a 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -684,8 +684,8 @@ [(#"40000" #"040000") (extract-tree id obj-ids tmp (build-path dest-dir fn))] [(#"120000") - (make-file-or-directory-link (build-path dest-dir fn) - (object->bytes tmp (this-object-location)))] + (make-file-or-directory-link (bytes->path (object->bytes tmp (this-object-location))) + (build-path dest-dir fn))] [(#"160000") ;; submodule; just make a directory placeholder (make-directory* (build-path dest-dir fn))] From d1a942be63b4e8ab9a064553ab3da9e8be3382a0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Oct 2015 09:26:03 -0600 Subject: [PATCH 290/381] net/git-commit: add a `#:strict-links?` argument Fail on checkout if it creates a symbolic link with an absolute path or a relative path with "..". Adjust `raco pkgs` to use `#:strict-links? #t`. --- racket/collects/net/git-checkout.rkt | 27 ++++++++++++++---------- racket/collects/pkg/private/download.rkt | 3 ++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index d20db03a2a..f41bb366f8 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -5,6 +5,7 @@ racket/port racket/string file/gunzip + file/private/check-path openssl/sha1 openssl net/url @@ -34,7 +35,8 @@ #:tmp-dir [given-tmp-dir #f] #:clean-tmp-dir? [clean-tmp-dir? (not given-tmp-dir)] #:verify-server? [verify? #t] - #:port [given-port #f]) + #:port [given-port #f] + #:strict-links? [strict-links? #f]) (let retry-loop ([given-depth given-depth]) (define tmp-dir (or given-tmp-dir (make-temporary-file "git~a" 'directory))) @@ -171,7 +173,8 @@ ;; Extract the tree from the packfile objects: (status "Extracting tree to ~a" dest-dir) (extract-commit-tree (hex-string->bytes commit) - obj-ids tmp dest-dir) + obj-ids tmp dest-dir + strict-links?) ;; Done; return checkout id (lambda () commit)) @@ -603,7 +606,7 @@ ;; extract-commit-tree : bytes (hash/c bytes object) tmp-info path -> void ;; Extract the designated commit to `dest-dir`, using objects from `tmp` -(define (extract-commit-tree obj-id obj-ids tmp dest-dir) +(define (extract-commit-tree obj-id obj-ids tmp dest-dir strict-links?) (define obj (hash-ref obj-ids obj-id)) (case (object-type obj) [(commit) @@ -614,7 +617,7 @@ (lambda (i) (extract-commit-info i obj-id)))) (define tree-id (hex-string->bytes tree-id-str)) - (extract-tree tree-id obj-ids tmp dest-dir)] + (extract-tree tree-id obj-ids tmp dest-dir strict-links?)] [(tag) (define commit-id-bstr (call-with-input-object @@ -627,9 +630,9 @@ (bytes->hex-string obj-id))) (cadr m)))) (define commit-id (hex-string->bytes (bytes->string/utf-8 commit-id-bstr))) - (extract-commit-tree commit-id obj-ids tmp dest-dir)] + (extract-commit-tree commit-id obj-ids tmp dest-dir strict-links?)] [(tree) - (extract-tree obj-id obj-ids tmp dest-dir)] + (extract-tree obj-id obj-ids tmp dest-dir strict-links?)] [else (error 'git-checkout "cannot extract tree from ~a: ~s" (object-type obj) @@ -657,9 +660,9 @@ (loop)) null)))) -;; extract-commit-tree : bytes (hash/c bytes object) tmp-info path -> void +;; extract-tree : bytes (hash/c bytes object) tmp-info path -> void ;; Extract the designated tree to `dest-dir`, using objects from `tmp` -(define (extract-tree tree-id obj-ids tmp dest-dir) +(define (extract-tree tree-id obj-ids tmp dest-dir strict-links?) (make-directory* dest-dir) (define tree-obj (hash-ref obj-ids tree-id)) (call-with-input-object @@ -682,10 +685,12 @@ [(#"100644" #"644") (copy-this-object #o644)] [(#"40000" #"040000") - (extract-tree id obj-ids tmp (build-path dest-dir fn))] + (extract-tree id obj-ids tmp (build-path dest-dir fn) strict-links?)] [(#"120000") - (make-file-or-directory-link (bytes->path (object->bytes tmp (this-object-location))) - (build-path dest-dir fn))] + (define target (bytes->path (object->bytes tmp (this-object-location)))) + (when strict-links? + (check-unpack-path 'git-checkout target)) + (make-file-or-directory-link target (build-path dest-dir fn))] [(#"160000") ;; submodule; just make a directory placeholder (make-directory* (build-path dest-dir fn))] diff --git a/racket/collects/pkg/private/download.rkt b/racket/collects/pkg/private/download.rkt index 47fc8e401b..822eb6df11 100644 --- a/racket/collects/pkg/private/download.rkt +++ b/racket/collects/pkg/private/download.rkt @@ -109,7 +109,8 @@ (define (strip-ending-newline s) (regexp-replace #rx"\n$" s "")) (log-pkg-debug (strip-ending-newline (apply format fmt args)))) - #:transport transport))) + #:transport transport + #:strict-links? #t))) (set! unpacked? #t) ;; package directory as ".tgz" so it can be cached: (parameterize ([current-directory dest-dir]) From 93d9826936b7fc159b469f4fbf57d6d417da26f7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Oct 2015 11:48:25 -0600 Subject: [PATCH 291/381] fix another problem with GC and place messages When a place message is deserialized by simply adopting the page containing the message, the adoption can trigger a garbage collection, but there's still a pointer to a chain of objects "in flight" in the thread, and a GC can discard the pairs that form the chain. --- racket/src/racket/src/place.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/racket/src/racket/src/place.c b/racket/src/racket/src/place.c index c17c84f42c..7ac5c6657e 100644 --- a/racket/src/racket/src/place.c +++ b/racket/src/racket/src/place.c @@ -2828,10 +2828,13 @@ static Scheme_Object *places_serialize(Scheme_Object *so, void **msg_memory, Sch #endif } -Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) +static Scheme_Object *places_deserialize(Scheme_Object *so, void *msg_memory, Scheme_Thread *from_p) /* The caller must immediately drop any reference to `so' and `msg_memory' after this function returns; otherwise, since the - `msg_memory' page may be deallocated, a GC could crash. */ + `msg_memory' page may be deallocated, a GC could crash. + Also, we have to clear out the in-flight references in `from_p` + before the pages are discarded or adopted (where the latter + can trigger a GC, which creates the main problem) */ { #if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) Scheme_Object *new_so = so; @@ -2842,13 +2845,18 @@ Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) /* small messages are deemed to be < 1k, this could be tuned in either direction */ if (GC_message_small_objects_size(msg_memory, 1024)) { new_so = do_places_deep_copy(so, mzPDC_UNCOPY, 1, NULL, NULL); + from_p->place_channel_msg_in_flight = NULL; + from_p->place_channel_msg_chain_in_flight = NULL; GC_dispose_short_message_allocator(msg_memory); /* from this point, we must return immediately, so that any reference to `so' can be dropped before GC. */ msg_memory = NULL; } else { + from_p->place_channel_msg_in_flight = NULL; + from_p->place_channel_msg_chain_in_flight = NULL; GC_adopt_message_allocator(msg_memory); + scheme_collect_garbage(); // REMOVEME msg_memory = NULL; #if !defined(SHARED_TABLES) new_so = do_places_deep_copy(so, mzPDC_DESER, 1, NULL, NULL); @@ -3549,9 +3557,9 @@ static Scheme_Object *place_async_try_receive_raw(Scheme_Place_Async_Channel *ch static void cleanup_msg_memmory(void *thread) { Scheme_Thread *p = thread; if (p->place_channel_msg_in_flight) { + p->place_channel_msg_chain_in_flight = NULL; GC_destroy_orphan_msg_memory(p->place_channel_msg_in_flight); p->place_channel_msg_in_flight = NULL; - p->place_channel_msg_chain_in_flight = NULL; } } @@ -3575,9 +3583,7 @@ static Scheme_Object *place_async_try_receive(Scheme_Place_Async_Channel *ch, in p->place_channel_msg_in_flight = msg_memory; p->place_channel_msg_chain_in_flight = msg_chain; log_received_msg(msg, msg_memory); - msg = scheme_places_deserialize(msg, msg_memory); - p->place_channel_msg_in_flight = NULL; - p->place_channel_msg_chain_in_flight = NULL; + msg = places_deserialize(msg, msg_memory, p); } END_ESCAPEABLE(); return msg; @@ -3602,9 +3608,7 @@ static Scheme_Object *place_channel_finish_ready(void *d, int argc, struct Schem msg = *(Scheme_Object **)d; BEGIN_ESCAPEABLE(cleanup_msg_memmory, p); - msg = scheme_places_deserialize(msg, p->place_channel_msg_in_flight); - p->place_channel_msg_in_flight = NULL; - p->place_channel_msg_chain_in_flight = NULL; + msg = places_deserialize(msg, p->place_channel_msg_in_flight, p); END_ESCAPEABLE(); return msg; From 2c7663eb5e36f2226c1d9457d3f5e94999a6dd29 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Oct 2015 12:50:08 -0600 Subject: [PATCH 292/381] remove accidentally committed explicit GC I even marked it "REMOVEME", but didn't look at the commit closely enough before pushing. --- racket/src/racket/src/place.c | 1 - 1 file changed, 1 deletion(-) diff --git a/racket/src/racket/src/place.c b/racket/src/racket/src/place.c index 7ac5c6657e..1403bdafe5 100644 --- a/racket/src/racket/src/place.c +++ b/racket/src/racket/src/place.c @@ -2856,7 +2856,6 @@ static Scheme_Object *places_deserialize(Scheme_Object *so, void *msg_memory, Sc from_p->place_channel_msg_in_flight = NULL; from_p->place_channel_msg_chain_in_flight = NULL; GC_adopt_message_allocator(msg_memory); - scheme_collect_garbage(); // REMOVEME msg_memory = NULL; #if !defined(SHARED_TABLES) new_so = do_places_deep_copy(so, mzPDC_DESER, 1, NULL, NULL); From 2516374744153cd571e18e773df04636fad930ce Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 3 Oct 2015 09:43:01 -0500 Subject: [PATCH 293/381] account for the added caveat line in the example error message dissection Thanks to Paolo G. Giarrusso for spotting this and proposing a fix --- .../scribblings/guide/contracts/simple-function.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/contracts/simple-function.scrbl b/pkgs/racket-doc/scribblings/guide/contracts/simple-function.scrbl index 872a2ea6fc..1110c48337 100644 --- a/pkgs/racket-doc/scribblings/guide/contracts/simple-function.scrbl +++ b/pkgs/racket-doc/scribblings/guide/contracts/simple-function.scrbl @@ -446,5 +446,5 @@ In general, each contract error message consists of six sections: @item{a description of the precise aspect of the contract that was violated, @lines[1 2]} @item{the complete contract plus a path into it showing which aspect was violated, @lines[3 2]} @item{the module where the contract was put (or, more generally, the boundary that the contract mediates), @lines[5 1]} - @item{who was blamed, @lines[6 1]} - @item{and the source location where the contract appears. @lines[7 1]}] + @item{who was blamed, @lines[6 2]} + @item{and the source location where the contract appears. @lines[8 1]}] From b92eac82ab05a432b99e53b43db0a8cf8ab18af3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 4 Oct 2015 20:30:17 -0600 Subject: [PATCH 294/381] patch Pango to make the system control font accessible The patch doesn't directly make the font accessible, but it provides a hook so that the font can be made accessible. --- racket/src/native-libs/build.rkt | 4 ++ .../patches/coretext-fontreg.patch | 57 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 racket/src/native-libs/patches/coretext-fontreg.patch diff --git a/racket/src/native-libs/build.rkt b/racket/src/native-libs/build.rkt index 820a2f988f..506ea17b63 100644 --- a/racket/src/native-libs/build.rkt +++ b/racket/src/native-libs/build.rkt @@ -122,6 +122,9 @@ ;; Enable kerning and set DPI to 72: (define-runtime-path coretext-patch "patches/coretext.patch") +;; Support registration of extra font families: +(define-runtime-path coretext-fontreg-patch "patches/coretext-fontreg.patch") + ;; Enable "symbol" fonts, and fix off-by-one: (define-runtime-path win32text-patch "patches/win32text.patch") @@ -433,6 +436,7 @@ '("--with-included-modules=yes" "--with-dynamic-modules=no")) #:patches (list coretext-patch + coretext-fontreg-patch win32text-patch))] [("gmp") (config #:patches (if gcc-4.0? (list gmp-weak-patch) null) #:configure (append diff --git a/racket/src/native-libs/patches/coretext-fontreg.patch b/racket/src/native-libs/patches/coretext-fontreg.patch new file mode 100644 index 0000000000..273166a1df --- /dev/null +++ b/racket/src/native-libs/patches/coretext-fontreg.patch @@ -0,0 +1,57 @@ +diff -u -r old/pango-1.36.6/pango/pangocoretext-fontmap.c new/pango-1.36.6/pango/pangocoretext-fontmap.c +--- old/pango-1.36.6/pango/pangocoretext-fontmap.c 2015-10-04 20:27:08.000000000 -0600 ++++ new/pango-1.36.6/pango/pangocoretext-fontmap.c 2015-10-04 20:25:23.000000000 -0600 +@@ -548,6 +548,53 @@ + pfclass->is_synthesized = pango_core_text_face_is_synthesized; + } + ++void pango_core_text_add_family_for_font_descriptors(PangoCoreTextFontMap *ctfontmap, ++ char *name, ++ int count, ++ CTFontDescriptorRef *descs) ++{ ++ PangoCoreTextFamily *family; ++ PangoCoreTextFace *face; ++ int i; ++ char *fold_name; ++ ++ fold_name = g_utf8_casefold (name, -1); ++ ++ if (g_hash_table_lookup (ctfontmap->families, fold_name)) { ++ g_free(fold_name); ++ return; ++ } ++ ++ family = g_object_new (PANGO_TYPE_CORE_TEXT_FAMILY, NULL); ++ family->family_name = g_strdup(name); ++ { ++ CFDictionaryRef dict; ++ CFNumberRef number; ++ SInt64 font_traits; ++ ++ dict = CTFontDescriptorCopyAttribute (descs[0], kCTFontTraitsAttribute); ++ number = (CFNumberRef)CFDictionaryGetValue (dict, ++ kCTFontSymbolicTrait); ++ ++ if (CFNumberGetValue (number, kCFNumberSInt64Type, &font_traits)) ++ { ++ if ((font_traits & kCTFontMonoSpaceTrait) == kCTFontMonoSpaceTrait) ++ family->is_monospace = TRUE; ++ } ++ } ++ g_hash_table_insert (ctfontmap->families, fold_name, family); ++ ++ family->n_faces = count; ++ family->faces = g_new (PangoFontFace *, family->n_faces); ++ ++ for (i = 0; i < count; i++) { ++ face = pango_core_text_face_from_ct_font_descriptor (descs[i]); ++ face->family = family; ++ ++ family->faces[i] = (PangoFontFace *)face; ++ } ++} ++ + /* + * PangoCoreTextFamily + */ From b0800dab16acb5d8337eb9532711a23559a07248 Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Fri, 5 Jun 2015 11:21:13 -0300 Subject: [PATCH 295/381] Typo --- pkgs/racket-doc/syntax/scribblings/define.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/syntax/scribblings/define.scrbl b/pkgs/racket-doc/syntax/scribblings/define.scrbl index e57c06e433..bff6b2aaa4 100644 --- a/pkgs/racket-doc/syntax/scribblings/define.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/define.scrbl @@ -27,7 +27,7 @@ If the definition is ill-formed, a syntax error is raised. If an expression context. The default value of @racket[check-context?] is @racket[#t]. -If @racket[opt-kws?] is @racket[#t], then arguments of the form +If @racket[opt+kws?] is @racket[#t], then arguments of the form @racket[[id expr]], @racket[keyword id], and @racket[keyword [id expr]] are allowed, and they are preserved in the expansion.} @@ -49,4 +49,4 @@ expr]] are allowed, and they are preserved in the expansion.} is true for uses of @racket[normalize-definition]. @history[#:added "6.1.1.8"] -} \ No newline at end of file +} From 09a2b630bc4020effbc3efabf7d3b78efb8828ee Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Fri, 5 Jun 2015 11:37:30 -0300 Subject: [PATCH 296/381] Generalize inferred names After some expansions, a expression with the syntax property 'inferred-name of 'x is converted to one with ('x . 'x), so it's not useful to get the name of a procedure. So we simplify the syntax property 'inferred-name to handle these cases. --- .../scribblings/reference/syntax-model.scrbl | 7 ++++ pkgs/racket-doc/syntax/scribblings/name.scrbl | 12 +++++- pkgs/racket-test-core/tests/racket/name.rktl | 21 +++++++++- racket/collects/racket/private/name.rkt | 18 ++++++--- racket/src/racket/src/compile.c | 39 +++++++++++++++++++ 5 files changed, 88 insertions(+), 9 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl index 6ca75808ee..d3cf4cb2af 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax-model.scrbl @@ -1101,6 +1101,13 @@ property value of @|void-const| hides a name that would otherwise be inferred from context (perhaps because a binding identifier's was automatically generated and should not be exposed). +To support the propagation and merging of consistent properties during +expansions, the value of the @racket['inferred-name] property can be a +tree formed with @racket[cons] where all of the leaves are the same. +For example, @racket[(cons 'name 'name)] is equivalent to +@racket['name], and @racket[(cons (void) (void))] is equivalent to +@|void-const|. + When an inferred name is not available, but a source location is available, a name is constructed using the source location information. Inferred and property-assigned names are also available diff --git a/pkgs/racket-doc/syntax/scribblings/name.scrbl b/pkgs/racket-doc/syntax/scribblings/name.scrbl index e932eff5f9..c9ad9ac6d1 100644 --- a/pkgs/racket-doc/syntax/scribblings/name.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/name.scrbl @@ -8,13 +8,21 @@ @defproc[(syntax-local-infer-name [stx syntax?] [use-local? any/c #t]) any/c]{ Similar to @racket[syntax-local-name], except that @racket[stx] is -checked for an @racket['inferred-name] property (which overrides any -inferred name). If neither @racket[syntax-local-name] nor +checked for an @racket['inferred-name] property that is a symbol +(which overrides any inferred name) or @|void-const|. +If neither @racket[syntax-local-name] nor @racket['inferred-name] produce a name, or if the @racket['inferred-name] property value is @|void-const|, then a name is constructed from the source-location information in @racket[stx], if any. If no name can be constructed, the result is @racket[#f]. +To support the propagation and merging of consistent properties during +expansions, the value of the @racket['inferred-name] property can be a +tree formed with @racket[cons] where all of the leaves are the same. +For example, @racket[(cons 'name 'name)] is equivalent to +@racket['name], and @racket[(cons (void) (void))] is equivalent to +@|void-const|. + If @racket[use-local?] is @racket[#f], then @racket[syntax-local-name] is not used. Provide @racket[use-local?] as @racket[#f] to construct a name for a syntax object that is not an expression currently being expanded.} diff --git a/pkgs/racket-test-core/tests/racket/name.rktl b/pkgs/racket-test-core/tests/racket/name.rktl index 151460f0f6..bea667ce5c 100644 --- a/pkgs/racket-test-core/tests/racket/name.rktl +++ b/pkgs/racket-test-core/tests/racket/name.rktl @@ -3,8 +3,8 @@ (load-relative "loadtest.rktl") -(require scheme/class) -(require scheme/unit) +(require racket/class) +(require racket/unit) (Section 'names) @@ -134,6 +134,23 @@ 5)) #rx"^(?!.*unmentionable)") +;; Test use of the 'inferred-name syntax property +(define-syntax (named-thunk1 stx) + (syntax-case stx () + [(_ v) + (syntax-property #'(lambda () 1) 'inferred-name (eval #'v))])) + +(test 'one object-name (let ([tmp (named-thunk1 'one)]) tmp)) +(test #t src-name? (object-name (let ([tmp (named-thunk1 (void))]) tmp))) +(test 'tmp object-name (let ([tmp (named-thunk1 #f)]) tmp)) +(test 'tmp object-name (let ([tmp (named-thunk1 1)]) tmp)) +(test 'tmp object-name (let ([tmp (named-thunk1 "one")]) tmp)) + +(test 'one object-name (let ([tmp (named-thunk1 (cons 'one 'one))]) tmp)) +(test #t src-name? (object-name (let ([tmp (named-thunk1 (cons (void) (void)))]) tmp))) +(test 'tmp object-name (let ([tmp (named-thunk1 (cons #f #f))]) tmp)) +(test 'tmp object-name (let ([tmp (named-thunk1 (cons 1 1))]) tmp)) +(test 'tmp object-name (let ([tmp (named-thunk1 (cons "one" "one"))]) tmp)) (test 'norm values (let-syntax ([m (lambda (stx) diff --git a/racket/collects/racket/private/name.rkt b/racket/collects/racket/private/name.rkt index bb0277ba60..26c5b98609 100644 --- a/racket/collects/racket/private/name.rkt +++ b/racket/collects/racket/private/name.rkt @@ -2,13 +2,12 @@ (module name '#%kernel (#%require "define.rkt" "small-scheme.rkt") (#%provide syntax-local-infer-name) - + (define syntax-local-infer-name (case-lambda [(stx use-local?) - (let-values ([(prop) (syntax-property stx 'inferred-name)]) - (or (and prop - (not (void? prop)) + (let-values ([(prop) (simplify-inferred-name (syntax-property stx 'inferred-name))]) + (or (and (symbol? prop) prop) (let ([n (and use-local? (not (void? prop)) @@ -33,4 +32,13 @@ (string->symbol (format "~a:~a:~a" s l c)) (let ([p (syntax-position stx)]) (string->symbol (format "~a::~a" s p)))))))))))] - [(stx) (syntax-local-infer-name stx #t)]))) + [(stx) (syntax-local-infer-name stx #t)])) + + (define (simplify-inferred-name name) + (if (pair? name) + (let ([name-car (simplify-inferred-name (car name))] + [name-cdr (simplify-inferred-name (cdr name))]) + (if (eq? name-car name-cdr) + name-car + name)) + name))) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 0787464bbd..a8be0877d0 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -383,11 +383,49 @@ static void bad_form(Scheme_Object *form, int l) l - 1, (l != 2) ? "s" : ""); } +static Scheme_Object *simplify_inferred_name(Scheme_Object *name); + +static Scheme_Object *simplify_inferred_name_k(void) +{ + Scheme_Thread *p = scheme_current_thread; + Scheme_Object *name = (Scheme_Object *)p->ku.k.p1; + + p->ku.k.p1 = NULL; + + return (void *)simplify_inferred_name(name); +} + + +static Scheme_Object *simplify_inferred_name(Scheme_Object *name) +{ + { +# include "mzstkchk.h" + { + Scheme_Thread *p = scheme_current_thread; + + p->ku.k.p1 = (void *)name; + + return scheme_handle_stack_overflow(simplify_inferred_name_k); + } + } + + if (SCHEME_PAIRP(name)) { + Scheme_Object *name_car = SCHEME_CAR(name), *name_cdr = SCHEME_CDR(name); + name_car = simplify_inferred_name(name_car); + name_cdr = simplify_inferred_name(name_cdr); + if (SAME_OBJ(name_car, name_cdr)) + return name_car; + } + + return name; +} + Scheme_Object *scheme_check_name_property(Scheme_Object *code, Scheme_Object *current_val) { Scheme_Object *name; name = scheme_stx_property(code, inferred_name_symbol, NULL); + name = simplify_inferred_name(name); if (name && SCHEME_SYMBOLP(name)) return name; else @@ -551,6 +589,7 @@ Scheme_Object *scheme_build_closure_name(Scheme_Object *code, Scheme_Comp_Env *e Scheme_Object *name; name = scheme_stx_property(code, inferred_name_symbol, NULL); + name = simplify_inferred_name(name); if (name && SCHEME_SYMBOLP(name)) { name = combine_name_with_srcloc(name, code, 0); } else if (name && SCHEME_VOIDP(name)) { From a729c028a6578fab54b908062d7688dd4a83e67e Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 29 May 2015 16:57:31 -0400 Subject: [PATCH 297/381] Add racket/os library. For now this just contains two functions from mzlib/os. --- .../scribblings/reference/os-lib.scrbl | 18 +++++ .../racket-doc/scribblings/reference/os.scrbl | 1 + racket/collects/racket/os.rkt | 68 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 pkgs/racket-doc/scribblings/reference/os-lib.scrbl create mode 100644 racket/collects/racket/os.rkt diff --git a/pkgs/racket-doc/scribblings/reference/os-lib.scrbl b/pkgs/racket-doc/scribblings/reference/os-lib.scrbl new file mode 100644 index 0000000000..dfa6827575 --- /dev/null +++ b/pkgs/racket-doc/scribblings/reference/os-lib.scrbl @@ -0,0 +1,18 @@ +#lang scribble/doc +@(require "mz.rkt" + (for-label racket/os)) + +@title[#:tag "os-lib"]{Additional Operating System Functions} + +@defmodule[racket/os]{The @racketmodname[racket/os] library + additional functions for querying the operating system.} + +@history[#:added "6.2.900.17"] + +@defproc[(gethostname) string?]{ + Returns a string for the current machine's hostname (including its domain). +} + +@defproc[(getpid) exact-integer?]{ + Returns an integer identifying the current process within the operating system. +} diff --git a/pkgs/racket-doc/scribblings/reference/os.scrbl b/pkgs/racket-doc/scribblings/reference/os.scrbl index 6bd6586204..4cac9878d0 100644 --- a/pkgs/racket-doc/scribblings/reference/os.scrbl +++ b/pkgs/racket-doc/scribblings/reference/os.scrbl @@ -14,3 +14,4 @@ @include-section["envvars.scrbl"] @include-section["runtime.scrbl"] @include-section["cmdline.scrbl"] +@include-section["os-lib.scrbl"] diff --git a/racket/collects/racket/os.rkt b/racket/collects/racket/os.rkt new file mode 100644 index 0000000000..05d8a059f0 --- /dev/null +++ b/racket/collects/racket/os.rkt @@ -0,0 +1,68 @@ +#lang racket/base + +;; Provides additional functions for querying OS information + +(require (prefix-in c: racket/contract) + racket/promise + ffi/unsafe + ffi/cvector + ffi/winapi) + +(provide (c:contract-out [getpid (c:-> exact-integer?)] + [gethostname (c:-> string?)])) + +(define kernel32 + (delay (and (eq? 'windows (system-type)) (ffi-lib "kernel32")))) + +(define (delay-ffi-obj name lib type) + (delay (get-ffi-obj name lib type))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; gethostname + +(define BUFFER-SIZE 1024) +(define (extract-terminated-string proc) + (let ([s (make-bytes BUFFER-SIZE)]) + (if (proc s BUFFER-SIZE) + (bytes->string/utf-8 (car (regexp-match #rx#"^[^\0]*" s))) + (error 'gethostname "could not get hostname")))) + +(define unix-gethostname + (delay-ffi-obj "gethostname" #f (_fun _bytes _int -> _int))) + +(define windows-getcomputername + (delay-ffi-obj "GetComputerNameExA" (force kernel32) + (_fun #:abi winapi _int _bytes _cvector -> _int))) + +(define (gethostname) + (case (system-type) + [(unix macosx) + (let ([ghn (force unix-gethostname)]) + (extract-terminated-string (lambda (s sz) (zero? (ghn s sz)))))] + [(windows) + (let ([gcn (force windows-getcomputername)] + [DNS_FULLY_QUALIFIED 3]) + (extract-terminated-string + (lambda (s sz) + (let ([sz_ptr (cvector _int sz)]) + (and (not (zero? (gcn DNS_FULLY_QUALIFIED s sz_ptr))) + (let ([sz (cvector-ref sz_ptr 0)]) + (when (sz . < . (bytes-length s)) (bytes-set! s sz 0)) + #t))))))] + [else #f])) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; getpid + +(define unix-getpid + (delay-ffi-obj "getpid" #f (_fun -> _int))) + +(define windows-getpid + (delay-ffi-obj "GetCurrentProcessId" (force kernel32) + (_fun #:abi winapi -> _int))) + +(define (getpid) + ((force (case (system-type) + [(macosx unix) unix-getpid] + [(windows) windows-getpid] + [else (error 'getpid "unknown platform ~e" (system-type))])))) From d988055a49a8f91b47cf5ecbcce655155c4bde75 Mon Sep 17 00:00:00 2001 From: Stefan Date: Sat, 26 Sep 2015 20:54:36 -0400 Subject: [PATCH 298/381] added crypto-random-bytes --- .../scribblings/reference/numbers.scrbl | 28 +++++++++++++++++-- racket/collects/racket/private/unix-rand.rkt | 15 ++++++++++ .../collects/racket/private/windows-rand.rkt | 22 +++++++++++++++ racket/collects/racket/random.rkt | 14 ++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 racket/collects/racket/private/unix-rand.rkt create mode 100644 racket/collects/racket/private/windows-rand.rkt create mode 100644 racket/collects/racket/random.rkt diff --git a/pkgs/racket-doc/scribblings/reference/numbers.scrbl b/pkgs/racket-doc/scribblings/reference/numbers.scrbl index 1d4ed6745f..ee9771adbe 100644 --- a/pkgs/racket-doc/scribblings/reference/numbers.scrbl +++ b/pkgs/racket-doc/scribblings/reference/numbers.scrbl @@ -4,7 +4,8 @@ racket/flonum racket/fixnum racket/unsafe/ops - racket/require)) + racket/require + racket/random)) @(define math-eval (make-base-eval)) @(interaction-eval #:eval math-eval (require racket/math)) @@ -835,6 +836,8 @@ both in binary and as integers. @; ------------------------------------------------------------------------ @subsection{Random Numbers} +@margin-note{When security is a concern, use @racket[crypto-random-bytes] instead of @racket[random].} + @defproc*[([(random [k (integer-in 1 4294967087)] [rand-gen pseudo-random-generator? (current-pseudo-random-generator)]) @@ -855,7 +858,6 @@ internal state for generating numbers. The random number generator uses a 54-bit version of L'Ecuyer's MRG32k3a algorithm @cite["L'Ecuyer02"].} - @defproc[(random-seed [k (integer-in 1 (sub1 (expt 2 31)))]) void?]{ @@ -923,6 +925,28 @@ range @racket[0] to @racket[4294944442], inclusive; at least one of the first three integers is non-zero; and at least one of the last three integers is non-zero. Otherwise, the result is @racket[#f].} +@; ------------------------------------------------------------------------ + +@subsection{System-Provided Randomness} + +@defmodule[racket/random]{The @racketmodname[racket/random] module +provides an interface to randomness from the underlying operating +system. Use @racket[crypto-random-bytes] +instead of @racket[random] wherever security is a concern.} + +@defproc[(crypto-random-bytes [n exact-positive-integer?]) + bytes?]{ + +Returns @racket[n] random bytes. On Unix systems, the bytes are +obtained from @filepath{/dev/urandom}, while Windows uses +the @tt{RtlGenRand} system function. + +@examples[ + (eval:alts (crypto-random-bytes 14) #"\0\1\1\2\3\5\b\r\25\"7Y\220\351") +] + +@history[#:added "6.2.900.17"]} + @; ------------------------------------------------------------------------ @subsection{Number--String Conversions} diff --git a/racket/collects/racket/private/unix-rand.rkt b/racket/collects/racket/private/unix-rand.rkt new file mode 100644 index 0000000000..d2c6a3d0cd --- /dev/null +++ b/racket/collects/racket/private/unix-rand.rkt @@ -0,0 +1,15 @@ +#lang racket/base +(provide crypto-random-unix-bytes) + +(define (check-urandom-exists) + (unless (file-exists? "/dev/urandom") + (raise (make-exn:fail:filesystem + "crypto-random-bytes: \"/dev/urandom\" does not exist" + (current-continuation-marks))))) + +; (: crypto-random-unix-bytes (-> Positive-Integer Bytes)) +(define (crypto-random-unix-bytes n) + (check-urandom-exists) + (call-with-input-file* "/dev/urandom" + (lambda (port) + (read-bytes n port)))) diff --git a/racket/collects/racket/private/windows-rand.rkt b/racket/collects/racket/private/windows-rand.rkt new file mode 100644 index 0000000000..ad4067de31 --- /dev/null +++ b/racket/collects/racket/private/windows-rand.rkt @@ -0,0 +1,22 @@ +#lang racket/base +(provide crypto-random-windows-bytes) + +(require ffi/unsafe + ffi/unsafe/define) + +(define-ffi-definer define-advapi (and (eq? (system-type) 'windows) (ffi-lib "Advapi32.dll")) + #:default-make-fail make-not-available) + +; supposed to be the same csprng as CryptGenRand, but with less overhead +; see Microsoft security dev Michael Howard: http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx +; this is for Windows XP and later only, but I doubt that's a problem +(define-advapi SystemFunction036 (_fun _pointer _ulong -> _bool)) + +; (: crypto-random-windows-bytes (-> Positive-Integer Bytes)) +(define (crypto-random-windows-bytes n) + (define rand-bytes-buf (make-bytes n)) + (if (SystemFunction036 rand-bytes-buf n) + rand-bytes-buf + (raise (make-exn:fail + "crypto-random-windows: SystemFunction036 failed to generate bytes" + (current-continuation-marks))))) diff --git a/racket/collects/racket/random.rkt b/racket/collects/racket/random.rkt new file mode 100644 index 0000000000..2978444c9b --- /dev/null +++ b/racket/collects/racket/random.rkt @@ -0,0 +1,14 @@ +#lang racket/base + +(require "private/unix-rand.rkt" "private/windows-rand.rkt" racket/contract/base) +(provide (contract-out [crypto-random-bytes (-> exact-nonnegative-integer? bytes?)])) + +; (: crypto-random-bytes (-> Positive-Integer Bytes)) +; returns n random bytes from the os. +(define (crypto-random-bytes n) + (case (system-type 'os) + [(unix macosx) (crypto-random-unix-bytes n)] + [(windows) (crypto-random-windows-bytes n)] + [else (raise (make-exn:fail:unsupported + "not supported on the current platform" + (current-continuation-marks)))])) From c9c03dd40bdc73176a4f1e9cc252f6f839c91b49 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 5 Oct 2015 13:28:53 -0600 Subject: [PATCH 299/381] regexp-replace*: recognize `\$` as empty string --- pkgs/racket-test-core/tests/racket/basic.rktl | 2 ++ racket/collects/racket/private/string.rkt | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/basic.rktl b/pkgs/racket-test-core/tests/racket/basic.rktl index 1e49626a45..49502be398 100644 --- a/pkgs/racket-test-core/tests/racket/basic.rktl +++ b/pkgs/racket-test-core/tests/racket/basic.rktl @@ -1121,6 +1121,8 @@ (test "x&cy&z" regexp-replace* #rx"a(.)" "xabcyawz" "\\&") (test "x\\cy\\z" regexp-replace* #rx"a(.)" "xabcyawz" "\\\\") +(test "ap0p0le" regexp-replace* #rx"p" "apple" "\\0\\$0") + ;; Test sub-matches with procedure replace (second example by synx) (test "myCERVEZA myMI Mi" regexp-replace* "([Mm])i ([a-zA-Z]*)" "mi cerveza Mi Mi Mi" diff --git a/racket/collects/racket/private/string.rkt b/racket/collects/racket/private/string.rkt index b4a7c9847c..298a873e4a 100644 --- a/racket/collects/racket/private/string.rkt +++ b/racket/collects/racket/private/string.rkt @@ -410,7 +410,9 @@ (or (and (equal? (char->integer #\&) next) #"&") (and (equal? (char->integer #\\) next) - #"\\"))) + #"\\") + (and (equal? (char->integer #\$) next) + #""))) => (lambda (s) (cons s (loop (add1 (cdar m)))))] [else From 3bcd153fb61ecaacb0ded5377f32d345c1d167f2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 5 Oct 2015 13:37:38 -0600 Subject: [PATCH 300/381] adjust copyright dates: 2014 -> 2015 Better late than never? --- README.txt | 2 +- pkgs/at-exp-lib/LICENSE.txt | 2 +- pkgs/base/LICENSE.txt | 2 +- pkgs/racket-doc/LICENSE.txt | 2 +- pkgs/racket-index/LICENSE.txt | 2 +- pkgs/racket-index/scribblings/main/license.scrbl | 2 +- pkgs/racket-lib/LICENSE.txt | 2 +- pkgs/racket-test-core/LICENSE.txt | 2 +- pkgs/racket-test/LICENSE.txt | 2 +- racket/src/native-libs/install.rkt | 2 +- racket/src/racket/dynsrc/mzdyn.c | 2 +- racket/src/racket/include/escheme.h | 2 +- racket/src/racket/include/scheme.h | 2 +- racket/src/racket/main.c | 2 +- racket/src/racket/sgc/sgc.c | 2 +- racket/src/racket/src/bignum.c | 2 +- racket/src/racket/src/bool.c | 2 +- racket/src/racket/src/builtin.c | 2 +- racket/src/racket/src/char.c | 2 +- racket/src/racket/src/compenv.c | 2 +- racket/src/racket/src/compile.c | 2 +- racket/src/racket/src/complex.c | 2 +- racket/src/racket/src/dynext.c | 2 +- racket/src/racket/src/env.c | 2 +- racket/src/racket/src/error.c | 2 +- racket/src/racket/src/eval.c | 2 +- racket/src/racket/src/file.c | 2 +- racket/src/racket/src/fun.c | 2 +- racket/src/racket/src/future.c | 2 +- racket/src/racket/src/hash.c | 2 +- racket/src/racket/src/jit.c | 2 +- racket/src/racket/src/jitalloc.c | 2 +- racket/src/racket/src/jitarith.c | 2 +- racket/src/racket/src/jitcall.c | 2 +- racket/src/racket/src/jitcommon.c | 2 +- racket/src/racket/src/jitinline.c | 2 +- racket/src/racket/src/jitprep.c | 2 +- racket/src/racket/src/jitstack.c | 2 +- racket/src/racket/src/jitstate.c | 2 +- racket/src/racket/src/letrec_check.c | 2 +- racket/src/racket/src/list.c | 2 +- racket/src/racket/src/marshal.c | 2 +- racket/src/racket/src/module.c | 2 +- racket/src/racket/src/mzrt.c | 2 +- racket/src/racket/src/mzsj86.c | 2 +- racket/src/racket/src/network.c | 2 +- racket/src/racket/src/numarith.c | 2 +- racket/src/racket/src/number.c | 2 +- racket/src/racket/src/numcomp.c | 2 +- racket/src/racket/src/nummacs.h | 2 +- racket/src/racket/src/numstr.c | 2 +- racket/src/racket/src/optimize.c | 2 +- racket/src/racket/src/place.c | 2 +- racket/src/racket/src/port.c | 2 +- racket/src/racket/src/portfun.c | 2 +- racket/src/racket/src/print.c | 2 +- racket/src/racket/src/rational.c | 2 +- racket/src/racket/src/read.c | 2 +- racket/src/racket/src/regexp.c | 2 +- racket/src/racket/src/resolve.c | 2 +- racket/src/racket/src/salloc.c | 2 +- racket/src/racket/src/schemef.h | 2 +- racket/src/racket/src/schemex.h | 2 +- racket/src/racket/src/schpriv.h | 2 +- racket/src/racket/src/sema.c | 2 +- racket/src/racket/src/setjmpup.c | 2 +- racket/src/racket/src/sfs.c | 2 +- racket/src/racket/src/string.c | 2 +- racket/src/racket/src/struct.c | 2 +- racket/src/racket/src/symbol.c | 2 +- racket/src/racket/src/syntax.c | 2 +- racket/src/racket/src/thread.c | 2 +- racket/src/racket/src/type.c | 2 +- racket/src/racket/src/validate.c | 2 +- racket/src/racket/src/vector.c | 2 +- racket/src/worksp/gracket/gracket.rc | 2 +- racket/src/worksp/mzcom/mzcom.rc | 2 +- racket/src/worksp/racket/racket.rc | 2 +- racket/src/worksp/starters/start.rc | 2 +- 79 files changed, 79 insertions(+), 79 deletions(-) diff --git a/README.txt b/README.txt index 98251bd1d6..e6c1d2d36e 100644 --- a/README.txt +++ b/README.txt @@ -5,7 +5,7 @@ License ------- Racket -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. Racket is distributed under the GNU Lesser General Public License (LGPL). This implies that you may link Racket into proprietary diff --git a/pkgs/at-exp-lib/LICENSE.txt b/pkgs/at-exp-lib/LICENSE.txt index c4b4b89e70..1f2645dc9c 100644 --- a/pkgs/at-exp-lib/LICENSE.txt +++ b/pkgs/at-exp-lib/LICENSE.txt @@ -1,5 +1,5 @@ at-exp-lib -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. This package is distributed under the GNU Lesser General Public License (LGPL). This means that you can link this package into proprietary diff --git a/pkgs/base/LICENSE.txt b/pkgs/base/LICENSE.txt index 4d1fbad852..7396cb7383 100644 --- a/pkgs/base/LICENSE.txt +++ b/pkgs/base/LICENSE.txt @@ -1,5 +1,5 @@ base -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. This package is distributed under the GNU Lesser General Public License (LGPL). This means that you can link this package into proprietary diff --git a/pkgs/racket-doc/LICENSE.txt b/pkgs/racket-doc/LICENSE.txt index 3685176031..51edf17571 100644 --- a/pkgs/racket-doc/LICENSE.txt +++ b/pkgs/racket-doc/LICENSE.txt @@ -1,5 +1,5 @@ racket-doc -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. This package is distributed under the GNU Lesser General Public License (LGPL). This means that you can link this package into proprietary diff --git a/pkgs/racket-index/LICENSE.txt b/pkgs/racket-index/LICENSE.txt index a918bb26ac..fd82edbca7 100644 --- a/pkgs/racket-index/LICENSE.txt +++ b/pkgs/racket-index/LICENSE.txt @@ -1,5 +1,5 @@ racket-index -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. This package is distributed under the GNU Lesser General Public License (LGPL). This means that you can link this package into proprietary diff --git a/pkgs/racket-index/scribblings/main/license.scrbl b/pkgs/racket-index/scribblings/main/license.scrbl index 52375b45d8..f2984b252f 100644 --- a/pkgs/racket-index/scribblings/main/license.scrbl +++ b/pkgs/racket-index/scribblings/main/license.scrbl @@ -26,7 +26,7 @@ directory for more information. @copyright{ Racket - Copyright (c) 2010-2014 PLT Design Inc. + Copyright (c) 2010-2015 PLT Design Inc. } Racket software includes or extends the following copyrighted material: diff --git a/pkgs/racket-lib/LICENSE.txt b/pkgs/racket-lib/LICENSE.txt index 2e774c53bf..9b2aface7f 100644 --- a/pkgs/racket-lib/LICENSE.txt +++ b/pkgs/racket-lib/LICENSE.txt @@ -1,5 +1,5 @@ racket-lib -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. This package is distributed under the GNU Lesser General Public License (LGPL). This means that you can link this package into proprietary diff --git a/pkgs/racket-test-core/LICENSE.txt b/pkgs/racket-test-core/LICENSE.txt index ddae070a6e..46232662cc 100644 --- a/pkgs/racket-test-core/LICENSE.txt +++ b/pkgs/racket-test-core/LICENSE.txt @@ -1,5 +1,5 @@ racket-test -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. This package is distributed under the GNU Lesser General Public License (LGPL). This means that you can link this package into proprietary diff --git a/pkgs/racket-test/LICENSE.txt b/pkgs/racket-test/LICENSE.txt index ddae070a6e..46232662cc 100644 --- a/pkgs/racket-test/LICENSE.txt +++ b/pkgs/racket-test/LICENSE.txt @@ -1,5 +1,5 @@ racket-test -Copyright (c) 2010-2014 PLT Design Inc. +Copyright (c) 2010-2015 PLT Design Inc. This package is distributed under the GNU Lesser General Public License (LGPL). This means that you can link this package into proprietary diff --git a/racket/src/native-libs/install.rkt b/racket/src/native-libs/install.rkt index 3dac095cf6..728d9e72ad 100644 --- a/racket/src/native-libs/install.rkt +++ b/racket/src/native-libs/install.rkt @@ -262,7 +262,7 @@ #:exists 'truncate (lambda (o) (displayln pkg-name o) - (displayln "Copyright (c) 2010-2014 PLT Design Inc." o) + (displayln "Copyright (c) 2010-2015 PLT Design Inc." o) (newline o) (displayln "This package is distributed under the GNU Lesser General Public" o) (displayln "License (LGPL). This means that you can link this package into" o) diff --git a/racket/src/racket/dynsrc/mzdyn.c b/racket/src/racket/dynsrc/mzdyn.c index c4767585bb..b0edc8e823 100644 --- a/racket/src/racket/dynsrc/mzdyn.c +++ b/racket/src/racket/dynsrc/mzdyn.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995 Matthew Flatt All rights reserved. diff --git a/racket/src/racket/include/escheme.h b/racket/src/racket/include/escheme.h index 509a98702e..6d117330f2 100644 --- a/racket/src/racket/include/escheme.h +++ b/racket/src/racket/include/escheme.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995 Matthew Flatt All rights reserved. diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index faa8842a2f..1563826591 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt All rights reserved. diff --git a/racket/src/racket/main.c b/racket/src/racket/main.c index 690c5d2068..0eba8e1523 100644 --- a/racket/src/racket/main.c +++ b/racket/src/racket/main.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2000 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/sgc/sgc.c b/racket/src/racket/sgc/sgc.c index 9739a4a8f4..0e8cea20d4 100644 --- a/racket/src/racket/sgc/sgc.c +++ b/racket/src/racket/sgc/sgc.c @@ -1,7 +1,7 @@ /* SenoraGC, a relatively portable conservative GC for a slightly cooperative environment - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1996-98 Matthew Flatt All rights reserved. diff --git a/racket/src/racket/src/bignum.c b/racket/src/racket/src/bignum.c index 46e6e66acd..51ec30b937 100644 --- a/racket/src/racket/src/bignum.c +++ b/racket/src/racket/src/bignum.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt, Scott Owens This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/bool.c b/racket/src/racket/src/bool.c index 5f0d5d4288..20cee7e098 100644 --- a/racket/src/racket/src/bool.c +++ b/racket/src/racket/src/bool.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/builtin.c b/racket/src/racket/src/builtin.c index 74d1a9e495..5ccb0167a6 100644 --- a/racket/src/racket/src/builtin.c +++ b/racket/src/racket/src/builtin.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/char.c b/racket/src/racket/src/char.c index 95743af00c..a0a19e7ee0 100644 --- a/racket/src/racket/src/char.c +++ b/racket/src/racket/src/char.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index 841ef961b3..f2676bd996 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index a8be0877d0..2e1bec2e0c 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/complex.c b/racket/src/racket/src/complex.c index 72a9f338c9..e913396d5f 100644 --- a/racket/src/racket/src/complex.c +++ b/racket/src/racket/src/complex.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/dynext.c b/racket/src/racket/src/dynext.c index a2f43ef5b7..42f24b9380 100644 --- a/racket/src/racket/src/dynext.c +++ b/racket/src/racket/src/dynext.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2002 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index e3299d8674..c68ae63652 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/error.c b/racket/src/racket/src/error.c index 191463cec6..fd768f074f 100644 --- a/racket/src/racket/src/error.c +++ b/racket/src/racket/src/error.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 214e4cfdf6..d8fcc1c5c6 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index 38666fa394..2d9c6efcb7 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index f75649c190..c1414f34a5 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/future.c b/racket/src/racket/src/future.c index 49acc6bc85..6a31e5aae0 100644 --- a/racket/src/racket/src/future.c +++ b/racket/src/racket/src/future.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/hash.c b/racket/src/racket/src/hash.c index 7013f3da7c..f2e995b6db 100644 --- a/racket/src/racket/src/hash.c +++ b/racket/src/racket/src/hash.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 4fd13aff1e..181a21c1b0 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/jitalloc.c b/racket/src/racket/src/jitalloc.c index 84482da8f1..9213bf8a7a 100644 --- a/racket/src/racket/src/jitalloc.c +++ b/racket/src/racket/src/jitalloc.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/jitarith.c b/racket/src/racket/src/jitarith.c index dac72dfc3a..4a81996ca9 100644 --- a/racket/src/racket/src/jitarith.c +++ b/racket/src/racket/src/jitarith.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index e567bfead0..eaba449d5d 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 86e01617a8..34d8f5eec9 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 0b3fb79efd..f22d78a755 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/jitprep.c b/racket/src/racket/src/jitprep.c index dc64a18ebe..ec147332d8 100644 --- a/racket/src/racket/src/jitprep.c +++ b/racket/src/racket/src/jitprep.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/jitstack.c b/racket/src/racket/src/jitstack.c index 8c0c1398f0..02a76732fd 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/jitstate.c b/racket/src/racket/src/jitstate.c index 6d6e6fbabf..42040bb6f2 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2006-2014 PLT Design Inc. + Copyright (c) 2006-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/letrec_check.c b/racket/src/racket/src/letrec_check.c index f112f33a92..328b2aa1dd 100644 --- a/racket/src/racket/src/letrec_check.c +++ b/racket/src/racket/src/letrec_check.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2013 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/list.c b/racket/src/racket/src/list.c index 60a99888e2..d253e78449 100644 --- a/racket/src/racket/src/list.c +++ b/racket/src/racket/src/list.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index b0e11d66c9..66a9e0750b 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index c0a2ee8718..c2770b925a 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/mzrt.c b/racket/src/racket/src/mzrt.c index 7cd89e26b6..bdaa9dc143 100644 --- a/racket/src/racket/src/mzrt.c +++ b/racket/src/racket/src/mzrt.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2009-2014 PLT Design Inc. + Copyright (c) 2009-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/mzsj86.c b/racket/src/racket/src/mzsj86.c index 26953efb8c..3ceb734c72 100644 --- a/racket/src/racket/src/mzsj86.c +++ b/racket/src/racket/src/mzsj86.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/network.c b/racket/src/racket/src/network.c index 77b29894ad..10af061f5b 100644 --- a/racket/src/racket/src/network.c +++ b/racket/src/racket/src/network.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/numarith.c b/racket/src/racket/src/numarith.c index 459ee0b59a..315d6a4034 100644 --- a/racket/src/racket/src/numarith.c +++ b/racket/src/racket/src/numarith.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/number.c b/racket/src/racket/src/number.c index 88f58afdb4..16b4eeee5d 100644 --- a/racket/src/racket/src/number.c +++ b/racket/src/racket/src/number.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/numcomp.c b/racket/src/racket/src/numcomp.c index 3cf454c411..a3923119c4 100644 --- a/racket/src/racket/src/numcomp.c +++ b/racket/src/racket/src/numcomp.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/nummacs.h b/racket/src/racket/src/nummacs.h index 43e8500db2..7109d75d0d 100644 --- a/racket/src/racket/src/nummacs.h +++ b/racket/src/racket/src/nummacs.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/numstr.c b/racket/src/racket/src/numstr.c index a82d68c794..0f4fb210ac 100644 --- a/racket/src/racket/src/numstr.c +++ b/racket/src/racket/src/numstr.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 953a0c7fe8..f1c0cd0cae 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/place.c b/racket/src/racket/src/place.c index 1403bdafe5..44faed0e92 100644 --- a/racket/src/racket/src/place.c +++ b/racket/src/racket/src/place.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2009-2014 PLT Design Inc. + Copyright (c) 2009-2015 PLT Design Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 8d5ee727f8..44d3c0e930 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/portfun.c b/racket/src/racket/src/portfun.c index 87202e62ca..ca962a45bc 100644 --- a/racket/src/racket/src/portfun.c +++ b/racket/src/racket/src/portfun.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index 6c705f55ee..efc1a1df30 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/rational.c b/racket/src/racket/src/rational.c index ad03d11b87..4dda7a6f94 100644 --- a/racket/src/racket/src/rational.c +++ b/racket/src/racket/src/rational.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 3ec0ef105e..0e108604bc 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/regexp.c b/racket/src/racket/src/regexp.c index 77081cba07..b2e7fa76cb 100644 --- a/racket/src/racket/src/regexp.c +++ b/racket/src/racket/src/regexp.c @@ -1,7 +1,7 @@ /* * @(#)regexp.c 1.3 of 18 April 87 * Revised for PLT Racket, 1995-2001 - * Copyright (c) 2004-2014 PLT Design Inc. + * Copyright (c) 2004-2015 PLT Design Inc. * * Copyright (c) 1986 by University of Toronto. * Written by Henry Spencer. Not derived from licensed software. diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 7cae5be45f..45b6031e3a 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/salloc.c b/racket/src/racket/src/salloc.c index f57ff8487d..5e4130fbf0 100644 --- a/racket/src/racket/src/salloc.c +++ b/racket/src/racket/src/salloc.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/schemef.h b/racket/src/racket/src/schemef.h index b59b1317e8..ba990ea7cb 100644 --- a/racket/src/racket/src/schemef.h +++ b/racket/src/racket/src/schemef.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt All rights reserved. diff --git a/racket/src/racket/src/schemex.h b/racket/src/racket/src/schemex.h index f120dbd7ea..4d95b96eb5 100644 --- a/racket/src/racket/src/schemex.h +++ b/racket/src/racket/src/schemex.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt All rights reserved. diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 3298dc2041..c0f5da41b2 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt All rights reserved. diff --git a/racket/src/racket/src/sema.c b/racket/src/racket/src/sema.c index 49ac297139..c0bffa8477 100644 --- a/racket/src/racket/src/sema.c +++ b/racket/src/racket/src/sema.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/setjmpup.c b/racket/src/racket/src/setjmpup.c index 8c18c5d660..27ee9a843f 100644 --- a/racket/src/racket/src/setjmpup.c +++ b/racket/src/racket/src/setjmpup.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/sfs.c b/racket/src/racket/src/sfs.c index 69b5294ec0..8196415d0b 100644 --- a/racket/src/racket/src/sfs.c +++ b/racket/src/racket/src/sfs.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/string.c b/racket/src/racket/src/string.c index 168ff2cf75..56026cd0f5 100644 --- a/racket/src/racket/src/string.c +++ b/racket/src/racket/src/string.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index dd07614798..840f03cfcf 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/symbol.c b/racket/src/racket/src/symbol.c index c417d6aeb6..ececb055d9 100644 --- a/racket/src/racket/src/symbol.c +++ b/racket/src/racket/src/symbol.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index dc318d5a4d..bcc5f263f4 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 2000-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index b7384d19b4..93a927bd79 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/type.c b/racket/src/racket/src/type.c index 61332e1069..a4ab0285a7 100644 --- a/racket/src/racket/src/type.c +++ b/racket/src/racket/src/type.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/validate.c b/racket/src/racket/src/validate.c index c73b0faea4..90e2806796 100644 --- a/racket/src/racket/src/validate.c +++ b/racket/src/racket/src/validate.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/racket/src/vector.c b/racket/src/racket/src/vector.c index 89f742b901..ddaf1c8adb 100644 --- a/racket/src/racket/src/vector.c +++ b/racket/src/racket/src/vector.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2014 PLT Design Inc. + Copyright (c) 2004-2015 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or diff --git a/racket/src/worksp/gracket/gracket.rc b/racket/src/worksp/gracket/gracket.rc index 25b8eda60d..4285e87b35 100644 --- a/racket/src/worksp/gracket/gracket.rc +++ b/racket/src/worksp/gracket/gracket.rc @@ -43,7 +43,7 @@ BEGIN VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" VALUE "FileVersion", MZSCHEME_VERSION "\0" - VALUE "LegalCopyright", "Copyright 1995-2014 PLT Design Inc.\0" + VALUE "LegalCopyright", "Copyright 1995-2015 PLT Design Inc.\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" VALUE "ProductVersion", MZSCHEME_VERSION "\0" diff --git a/racket/src/worksp/mzcom/mzcom.rc b/racket/src/worksp/mzcom/mzcom.rc index f5491678fb..4f5554d967 100644 --- a/racket/src/worksp/mzcom/mzcom.rc +++ b/racket/src/worksp/mzcom/mzcom.rc @@ -58,7 +58,7 @@ BEGIN VALUE "FileDescription", "MzCOM Module" VALUE "FileVersion", MZSCHEME_VERSION "\0" VALUE "InternalName", "MzCOM" - VALUE "LegalCopyright", "Copyright 2000-2014 PLT Design Inc." + VALUE "LegalCopyright", "Copyright 2000-2015 PLT Design Inc." VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" VALUE "ProductVersion", MZSCHEME_VERSION "\0" diff --git a/racket/src/worksp/racket/racket.rc b/racket/src/worksp/racket/racket.rc index 8daf0caf81..9bbc8a1fe7 100644 --- a/racket/src/worksp/racket/racket.rc +++ b/racket/src/worksp/racket/racket.rc @@ -43,7 +43,7 @@ BEGIN VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" VALUE "FileVersion", MZSCHEME_VERSION "\0" - VALUE "LegalCopyright", "Copyright 1995-2014 PLT Design Inc.\0" + VALUE "LegalCopyright", "Copyright 1995-2015 PLT Design Inc.\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" VALUE "ProductVersion", MZSCHEME_VERSION "\0" diff --git a/racket/src/worksp/starters/start.rc b/racket/src/worksp/starters/start.rc index 307d954b41..cfec867857 100644 --- a/racket/src/worksp/starters/start.rc +++ b/racket/src/worksp/starters/start.rc @@ -51,7 +51,7 @@ BEGIN #ifdef MZSTART VALUE "InternalName", "mzstart\0" #endif - VALUE "LegalCopyright", "Copyright 1996-2014 PLT Design Inc.\0" + VALUE "LegalCopyright", "Copyright 1996-2015 PLT Design Inc.\0" #ifdef MRSTART VALUE "OriginalFilename", "MrStart.exe\0" #endif From f86c5dfe0af4718af5af84a04009e160a8222d44 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 5 Oct 2015 17:40:19 -0600 Subject: [PATCH 301/381] document `openssl/libcrypto` and `openssl/libssl` --- pkgs/racket-doc/openssl/openssl.scrbl | 60 ++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/openssl/openssl.scrbl b/pkgs/racket-doc/openssl/openssl.scrbl index e3802d248b..2562743e47 100644 --- a/pkgs/racket-doc/openssl/openssl.scrbl +++ b/pkgs/racket-doc/openssl/openssl.scrbl @@ -4,7 +4,10 @@ (for-label openssl racket openssl/sha1 - openssl/md5)) + openssl/md5 + openssl/libcrypto + openssl/libssl + (only-in ffi/unsafe ffi-lib ffi-lib?))) @title{OpenSSL: Secure Communication} @@ -820,3 +823,58 @@ The @racket[md5] function composes @racket[bytes->hex-string] with Returns a 16-byte byte string that represents the MD5 hash of the content from @racket[in], consuming all of the input from @racket[in] until an end-of-file.} + +@; ---------------------------------------------------------------------- + +@(define foreign-doc '(lib "scribblings/foreign/foreign.scrbl")) + +@section[#:tag "libcrypto"]{The @filepath{libcrypto} Shared Library} + +@defmodule[openssl/libcrypto]{The @racketmodname[openssl/libcrypto] +library provides a @tech[#:doc foreign-doc]{foreign-library value} for +the @filepath{libcrypto} shared library.} + + +@defthing[libcrypto (or/c #f ffi-lib?)]{ + +Returns a @tech[#:doc foreign-doc]{foreign-library value} for +@filepath{libcrypto}, or @racket[#f] if the library could not be found +or loaded. The load attempt uses the versions specified by +@racket[openssl-lib-versions].} + +@defthing[libcrypto-load-fail-reason (or/c #f string?)]{ + +Either @racket[#f] when @racket[libcrypto] is non-@racket[#f], or a +string when @racket[libcrypto] is @racket[#f]. In the latter case, the +string provides an error message for the attempt to load +@filepath{libcrypto}.} + + +@defthing[openssl-lib-versions (listof string?)]{ + +A list of versions that are tried for loading @filepath{libcrypto}. +The list of version strings is suitable as a second argument to +@racket[ffi-lib].} + +@; ---------------------------------------------------------------------- + +@section[#:tag "libssl"]{The @filepath{libssl} Shared Library} + +@defmodule[openssl/libssl]{The @racketmodname[openssl/libssl] +library provides a @tech[#:doc foreign-doc]{foreign-library value} for +the @filepath{libssl} shared library.} + + +@defthing[libssl (or/c #f ffi-lib?)]{ + +Returns a @tech[#:doc foreign-doc]{foreign-library value} for +@filepath{libssl}, or @racket[#f] if the library could not be found +or loaded. The load attempt uses the versions specified by +@racket[openssl-lib-versions].} + +@defthing[libssl-load-fail-reason (or/c #f string?)]{ + +Either @racket[#f] when @racket[libssl] is non-@racket[#f], or a +string when @racket[libssl] is @racket[#f]. In the latter case, the +string provides an error message for the attempt to load +@filepath{libssl}.} From 4d3852ae69c4f9f913fed2827e237ab9d7d91b63 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 6 Oct 2015 09:31:47 -0600 Subject: [PATCH 302/381] add indirection on thread start to avoid ObjC exception issues In Mac OS X 10.11, something about the use of exceptions triggers a libunwind stack traversal, and that traversal runs into trouble with Racket's stack mangling for threads. Inserting generated code in the stack frame sequence causes libunwind to give up and avoids a crash (e.g., with `-j -l drracket` on startup). --- racket/src/racket/src/jit.h | 1 + racket/src/racket/src/jitcommon.c | 27 +++++++++++++++++++++++++++ racket/src/racket/src/jitstack.c | 16 ++++++++++++++++ racket/src/racket/src/schpriv.h | 3 +++ racket/src/racket/src/thread.c | 9 +++++++-- 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index f921be2fd5..c72762ed7d 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -348,6 +348,7 @@ struct scheme_jit_common_record { void *list_ref_code, *list_tail_code; void *finish_tail_call_code, *finish_tail_call_fixup_code; void *module_run_start_code, *module_exprun_start_code, *module_start_start_code; + void *thread_start_child_code; void *box_flonum_from_stack_code, *box_flonum_from_reg_code; void *fl1_fail_code[JIT_NUM_FL_KINDS], *fl2rr_fail_code[2][JIT_NUM_FL_KINDS]; void *fl2fr_fail_code[2][JIT_NUM_FL_KINDS], *fl2rf_fail_code[2][JIT_NUM_FL_KINDS]; diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 34d8f5eec9..f2f2619a16 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -3639,6 +3639,33 @@ static int more_common0(mz_jit_state *jitter, void *_data) scheme_jit_register_sub_func(jitter, sjc.module_start_start_code, scheme_eof); } + /* *** thread_start_child_code *** */ + /* A simple indirection to generate code that libunwind can't follow, + particularly as used by exceptions in the Objective-C runtime */ + { + int in; + + sjc.thread_start_child_code = jit_get_ip(); + jit_prolog(2); + in = jit_arg_p(); + jit_getarg_p(JIT_R0, in); /* child */ + in = jit_arg_p(); + jit_getarg_p(JIT_R1, in); /* child_thunk */ + CHECK_LIMIT(); + mz_push_locals(); + + jit_prepare(2); + jit_pusharg_p(JIT_R1); + jit_pusharg_p(JIT_R0); + (void)mz_finish(scheme_do_thread_start_child); + CHECK_LIMIT(); + mz_pop_locals(); + jit_ret(); + CHECK_LIMIT(); + + scheme_jit_register_sub_func(jitter, sjc.thread_start_child_code, scheme_eof); + } + return 1; } diff --git a/racket/src/racket/src/jitstack.c b/racket/src/racket/src/jitstack.c index 02a76732fd..5b18d41405 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -689,6 +689,7 @@ void scheme_jit_now(Scheme_Object *f) typedef void *(*Module_Run_Proc)(Scheme_Env *menv, Scheme_Env *env, Scheme_Object **name); typedef void *(*Module_Exprun_Proc)(Scheme_Env *menv, int set_ns, Scheme_Object **name); typedef void *(*Module_Start_Proc)(struct Start_Module_Args *a, Scheme_Object **name); +typedef void (*Thread_Start_Child_Proc)(Scheme_Thread *child, Scheme_Object *child_thunk); void *scheme_module_run_start(Scheme_Env *menv, Scheme_Env *env, Scheme_Object *name) { @@ -717,8 +718,23 @@ void *scheme_module_start_start(struct Start_Module_Args *a, Scheme_Object *name return scheme_module_start_finish(a); } +void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk) +{ + Thread_Start_Child_Proc proc = (Thread_Start_Child_Proc)sjc.thread_start_child_code; + if (proc) + proc(child, child_thunk); + else + scheme_do_thread_start_child(child, child_thunk); +} + + #else void* scheme_jit_find_code_end(void *p) { return NULL; } +void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk) +{ + return scheme_do_thread_start_child(child, child_thunk); +} + #endif diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index c0f5da41b2..0a25dc45b4 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -667,6 +667,9 @@ void scheme_suspend_remembered_threads(void); void scheme_resume_remembered_threads(void); #endif +void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk); +void scheme_do_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk); + int scheme_wait_until_suspend_ok(void); #ifdef MZ_USE_MZRT diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 93a927bd79..62adb3f330 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2014 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or @@ -3167,6 +3167,11 @@ static void start_child(Scheme_Thread * volatile child, } } +void scheme_do_thread_start_child(Scheme_Thread *child, Scheme_Object *child_eval) +{ + return start_child(child, child_eval); +} + static Scheme_Object *make_subprocess(Scheme_Object *child_thunk, void *child_start, Scheme_Config *config, @@ -3223,7 +3228,7 @@ static Scheme_Object *make_subprocess(Scheme_Object *child_thunk, child->stack_start = child_start; /* Sets the child's jmpbuf for swapping in later: */ - start_child(child, child_thunk); + scheme_thread_start_child(child, child_thunk); if (scheme_notify_multithread && turn_on_multi) { scheme_notify_multithread(1); From a5f6bf34dc75e33dd8a09d6ee7c9ea509395feb2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 6 Oct 2015 16:40:00 -0600 Subject: [PATCH 303/381] raco pkg: refine handling of HTTP status codes Treat only 404 and 410 as "not found" errors, retry on 5xx errors, and treat anything else as an error insteda of "not found". --- pkgs/racket-test/tests/pkg/basic-index.rkt | 23 ++++++- pkgs/racket-test/tests/pkg/tests-install.rkt | 3 + racket/collects/pkg/private/catalog.rkt | 15 +--- racket/collects/pkg/private/download.rkt | 3 +- racket/collects/pkg/private/network.rkt | 72 ++++++++++++++------ racket/collects/pkg/private/stage.rkt | 5 +- 6 files changed, 82 insertions(+), 39 deletions(-) diff --git a/pkgs/racket-test/tests/pkg/basic-index.rkt b/pkgs/racket-test/tests/pkg/basic-index.rkt index 57bd17e7c3..8c5285eec5 100644 --- a/pkgs/racket-test/tests/pkg/basic-index.rkt +++ b/pkgs/racket-test/tests/pkg/basic-index.rkt @@ -9,20 +9,39 @@ #"text/s-expr" empty (λ (op) (write v op)))) +(define error-count (random 25)) +(printf "Server error error generator starts as ~s\n" error-count) + (define (pkg-index/basic pkg-name->info all-pkgs) (define (write-info req pkg-name) - (response/sexpr (pkg-name->info pkg-name))) + (define i (pkg-name->info pkg-name)) + ;; Every 25 reseponses or so, generate a 5xx server error; + ;; retries should mask the error: + (set! error-count (add1 error-count)) + (cond + [(zero? (modulo error-count 5)) + (response 500 #"Oops" (current-seconds) #f empty void)] + [i (response/sexpr i)] + [else + ;; "Randomly" return #f or a 404, either of which should be + ;; treated as not-found failure: + (if (odd? error-count) + (response 404 #"Not Found" (current-seconds) #f empty void) + (response/sexpr #f))])) (define-values (dispatch get-url) (dispatch-rules [("pkgs-all") (lambda (req) (response/sexpr (all-pkgs)))] [("pkgs") (lambda (req) (response/sexpr (hash-keys (all-pkgs))))] + [("pkg" "broken") + (lambda (req) + (response 401 #"Broken" (current-seconds) #f empty void))] [("pkg" (string-arg)) write-info])) dispatch) (provide/contract [pkg-index/basic - (-> (-> string? (hash/c symbol? any/c)) + (-> (-> string? (or/c #f (hash/c symbol? any/c))) (-> hash?) (-> request? response?))]) diff --git a/pkgs/racket-test/tests/pkg/tests-install.rkt b/pkgs/racket-test/tests/pkg/tests-install.rkt index fe00d967a9..78b6bdc4e0 100644 --- a/pkgs/racket-test/tests/pkg/tests-install.rkt +++ b/pkgs/racket-test/tests/pkg/tests-install.rkt @@ -69,6 +69,9 @@ (shelly-case "fails due to unrecognized scheme" $ "raco pkg install magic://download" =exit> 1) + (shelly-case + "fails due to 401 status result" + $ "raco pkg install broken" =exit> 1 =stderr> #rx"401") (shelly-case "local directory name fails because not inferred as such (inferred as package name)" $ "raco pkg install test-pkgs" =exit> 1) diff --git a/racket/collects/pkg/private/catalog.rkt b/racket/collects/pkg/private/catalog.rkt index 2b0ea8d838..bde12a9243 100644 --- a/racket/collects/pkg/private/catalog.rkt +++ b/racket/collects/pkg/private/catalog.rkt @@ -224,7 +224,7 @@ " response: ~v") (url->string url) s))]) - (define bytes (call-with-url url port->bytes)) + (define bytes (call/input-url+200 url port->bytes #:who who)) ((if bytes (with-handlers ([exn:fail:read? (lambda (exn) (lambda () (failure bytes)))]) @@ -235,17 +235,6 @@ (failure bytes)))) (lambda () (failure #f))))) -;; uses a custodian to avoid leaks: -(define (call-with-url url handler) - (call-with-network-retries - (lambda () - (define-values (p hs) - (get-pure-port/headers url #:redirections 25 #:status? #t)) - (begin0 - (and (string=? "200" (substring hs 9 12)) - (handler p)) - (close-input-port p))))) - (define (db-pkg-info pkg details?) (if details? (let ([tags (db:get-pkg-tags (db:pkg-name pkg) @@ -281,7 +270,7 @@ (add-version-query (combine-url/relative i "pkgs")) (lambda (l) (and (list? l) - (andmap string? l))))) + (andmap string? l))))) ;; Local database: (lambda () (map db:pkg-name (db:get-pkgs))) diff --git a/racket/collects/pkg/private/download.rkt b/racket/collects/pkg/private/download.rkt index 822eb6df11..781e1e0d99 100644 --- a/racket/collects/pkg/private/download.rkt +++ b/racket/collects/pkg/private/download.rkt @@ -69,7 +69,8 @@ url (λ (ip) (copy-port ip op)) #:auto-retry? #f - #:failure + #:who 'download + #:not-found-handler (lambda (reply-s) (pkg-error (~a "error downloading package\n" " URL: ~a\n" diff --git a/racket/collects/pkg/private/network.rkt b/racket/collects/pkg/private/network.rkt index 7ee8ae3f8f..159e1f7283 100644 --- a/racket/collects/pkg/private/network.rkt +++ b/racket/collects/pkg/private/network.rkt @@ -1,10 +1,14 @@ #lang racket/base (require net/url + racket/format "print.rkt" "config.rkt") (provide call-with-network-retries - call/input-url+200) + call/input-url+200 + exn:fail:can-retry) + +(struct exn:fail:can-retry exn:fail ()) (define NETWORK-INITIAL-PAUSE 0.1) @@ -15,16 +19,18 @@ (define (call-with-network-retries thunk) (define retry-count (get-network-retries)) (let loop ([retries 0] [pause-time NETWORK-INITIAL-PAUSE]) - (with-handlers* ([exn:fail:network? (lambda (exn) - (cond - [(retries . >= . retry-count) - (raise exn)] - [else - ;; Pause, then try again - (log-pkg-info "Network error; retrying after ~as" - pause-time) - (sleep pause-time) - (loop (add1 retries) (* 2 pause-time))]))]) + (define (maybe-retry exn) + (cond + [(retries . >= . retry-count) + (raise exn)] + [else + ;; Pause, then try again + (log-pkg-info "Network error; retrying after ~as" + pause-time) + (sleep pause-time) + (loop (add1 retries) (* 2 pause-time))])) + (with-handlers* ([exn:fail:network? maybe-retry] + [exn:fail:can-retry? maybe-retry]) (define c (make-custodian)) (parameterize ([current-custodian c]) (dynamic-wind @@ -33,20 +39,42 @@ (lambda () (custodian-shutdown-all c))))))) -(define (call/input-url+200 u fun +(define success-codes '(200)) +(define not-found-codes '(404 410)) + +(define other-retry-codes '(408)) ; not counting 5xx +(define (retry-code? c) + (or (and (integer? c) (<= 500 c 599)) + (memv c other-retry-codes))) + +(define (call/input-url+200 url handler + #:who [who 'download] #:auto-retry? [auto-retry? #t] #:headers [headers '()] - #:failure [fail-k (lambda (s) #f)]) + #:not-found-handler [not-found-handler (lambda (s) #f)]) ((if auto-retry? call-with-network-retries (lambda (f) (f))) (lambda () - #;(printf "\t\tReading ~a\n" (url->string u)) - (define-values (ip hs) (get-pure-port/headers u headers - #:redirections 25 - #:status? #t)) - (if (string=? "200" (substring hs 9 12)) - (begin0 - (fun ip) - (close-input-port ip)) - (fail-k hs))))) + (define-values (p hs) + (get-pure-port/headers url headers + #:redirections 25 + #:status? #t)) + (define status (string->number (substring hs 9 12))) + (cond + [(memv status success-codes) + (begin0 + (handler p) + (close-input-port p))] + [(memv status not-found-codes) + (close-input-port p) + (not-found-handler hs)] + [else + (raise ((if (retry-code? status) exn:fail:can-retry exn:fail) + (format (~a "~a: error from server\n" + " URL: ~a\n" + " status code: ~a") + who + (url->string url) + status) + (current-continuation-marks)))])))) diff --git a/racket/collects/pkg/private/stage.rkt b/racket/collects/pkg/private/stage.rkt index 52bc8d457b..fb8f3ffda4 100644 --- a/racket/collects/pkg/private/stage.rkt +++ b/racket/collects/pkg/private/stage.rkt @@ -434,6 +434,7 @@ (make-directory* package-path) (define manifest (call/input-url+200 + #:who 'download-manifest (url-like "MANIFEST") port->lines)) (unless manifest @@ -773,6 +774,7 @@ (define api-bs (call/input-url+200 api-u port->bytes + #:who 'query-github #:headers (list (format "User-Agent: raco-pkg/~a" (version))))) (unless api-bs (error 'package-url->checksum @@ -801,7 +803,8 @@ (download-printf "Downloading checksum for ~a\n" pkg-name) (log-pkg-debug "Downloading checksum as ~a" u) (call/input-url+200 (string->url u) - port->string)])) + port->string + #:who 'download-checksum)])) (define (check-checksum given-checksum checksum what pkg-src cached-url) (when (and given-checksum From 85c1ba55f37e1c41005cb9a751271b07af5a086e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 6 Oct 2015 19:06:07 -0600 Subject: [PATCH 304/381] fix native-stacktrace interaction with thread start Repairs 4d3852ae69. --- racket/src/racket/src/jitcommon.c | 3 ++- racket/src/racket/src/jitstack.c | 1 + racket/src/racket/src/thread.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index f2f2619a16..e58e30ec06 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -3663,7 +3663,8 @@ static int more_common0(mz_jit_state *jitter, void *_data) jit_ret(); CHECK_LIMIT(); - scheme_jit_register_sub_func(jitter, sjc.thread_start_child_code, scheme_eof); + /* No scheme_jit_register_sub_func, because we don't want to try to + traverse past this frame for a native stack trace. */ } return 1; diff --git a/racket/src/racket/src/jitstack.c b/racket/src/racket/src/jitstack.c index 5b18d41405..52fe69a40f 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -719,6 +719,7 @@ void *scheme_module_start_start(struct Start_Module_Args *a, Scheme_Object *name } void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk) + XFORM_SKIP_PROC { Thread_Start_Child_Proc proc = (Thread_Start_Child_Proc)sjc.thread_start_child_code; if (proc) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 62adb3f330..c90024a925 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -3168,6 +3168,7 @@ static void start_child(Scheme_Thread * volatile child, } void scheme_do_thread_start_child(Scheme_Thread *child, Scheme_Object *child_eval) + XFORM_SKIP_PROC { return start_child(child, child_eval); } From 7555d022db7293db63ef93e81448d28ee63cd0cf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 8 Oct 2015 10:53:23 -0600 Subject: [PATCH 305/381] for CPP, detect `__linux__`, etc., instead of `linux`, etc. When a compiler is run in standards mode, predefined macros that do not start with "_" are dropped, so use the "_" versions consistently. Whether or not Racket itself would compile in standards mode, the Racket headers should be able to work that way --- at least on Unix platforms. --- racket/src/racket/main.c | 2 +- racket/src/racket/sconfig.h | 30 ++++++++++++------------ racket/src/racket/sgc/autostat.inc | 2 +- racket/src/racket/src/future.c | 4 ++-- racket/src/racket/src/unwind/libunwind.h | 4 ++-- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/racket/src/racket/main.c b/racket/src/racket/main.c index 0eba8e1523..2c65759161 100644 --- a/racket/src/racket/main.c +++ b/racket/src/racket/main.c @@ -163,7 +163,7 @@ extern Scheme_Object *scheme_initialize(Scheme_Env *env); /* OS process name */ /*========================================================================*/ -#if defined(linux) +#if defined(__linux__) # include # ifdef PR_SET_NAME # define CAN_SET_OS_PROCESS_NAME 1 diff --git a/racket/src/racket/sconfig.h b/racket/src/racket/sconfig.h index 2c4455743d..f6e90bc29c 100644 --- a/racket/src/racket/sconfig.h +++ b/racket/src/racket/sconfig.h @@ -85,7 +85,7 @@ # include # ifdef ECHRNG /* Solaris */ -# if defined(i386) +# if defined(__i386__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-solaris" # elif defined(__x86_64) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "x86_64-solaris" @@ -121,7 +121,7 @@ # define SUBPROCESS_USE_FORK1 # endif -# ifdef i386 +# ifdef __i386__ # define MZ_USE_JIT_I386 # define MZ_JIT_USE_MPROTECT # elif defined(__x86_64) @@ -159,7 +159,7 @@ /************** Linux with gcc ****************/ -#if defined(linux) +#if defined(__linux__) # ifdef __ANDROID__ # define SPLS_LINUX "android" @@ -167,13 +167,13 @@ # define SPLS_LINUX "linux" # endif -# if defined(i386) +# if defined(__i386__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-"SPLS_LINUX # define REGISTER_POOR_MACHINE # define MZ_TRY_EXTFLONUMS # define ASM_DBLPREC_CONTROL_87 # endif -# if defined(powerpc) +# if defined(__powerpc__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "ppc-"SPLS_LINUX # endif # if defined(__mc68000__) @@ -237,7 +237,7 @@ # define FLAGS_ALREADY_SET -#if defined(i386) +#if defined(__i386__) # define MZ_USE_JIT_I386 # define MZ_JIT_USE_MPROTECT # define MZ_USE_DWARF_LIBUNWIND @@ -247,7 +247,7 @@ # define MZ_JIT_USE_MPROTECT # define MZ_USE_DWARF_LIBUNWIND #endif -#if defined(powerpc) +#if defined(__powerpc__) # define MZ_USE_JIT_PPC #endif # if defined(__arm__) @@ -263,9 +263,9 @@ #if defined(__NetBSD__) -#if defined(i386) +#if defined(__i386__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-netbsd" -#elif defined(powerpc) +#elif defined(__powerpc__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "ppc-netbsd" #elif defined(__x86_64__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "x86_64-netbsd" @@ -295,11 +295,11 @@ # define USE_DIVIDE_MAKE_INFINITY #endif -#if defined(i386) +#if defined(__i386__) # define MZ_USE_JIT_I386 # define MZ_JIT_USE_MPROTECT #endif -#if defined(powerpc) +#if defined(__powerpc__) # define MZ_USE_JIT_PPC #endif #if defined(__x86_64__) @@ -507,7 +507,7 @@ /************** SGI/IRIX with SGI cc ****************/ #if (defined(mips) || defined(__mips)) \ - && !(defined(ultrix) || defined(__ultrix) || defined(linux) || defined(__OpenBSD__)) + && !(defined(ultrix) || defined(__ultrix) || defined(__linux__) || defined(__OpenBSD__)) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "mips-irix" @@ -552,7 +552,7 @@ /************** ALPHA/OSF1 with gcc ****************/ # if (defined(__alpha) || defined(__alpha__)) \ - && !defined(linux) && !defined(__NetBSD__) && !defined(__OpenBSD__) + && !defined(__linux__) && !defined(__NetBSD__) && !defined(__OpenBSD__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "alpha-osf1" @@ -925,7 +925,7 @@ #if defined(__QNX__) -#if defined(i386) +#if defined(__i386__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-qnx" #endif # define ASSUME_FIXED_STACK_SIZE @@ -944,7 +944,7 @@ # define BROKEN_READLINK_NUL_TERMINATOR -#if defined(i386) +#if defined(__i386__) # define MZ_USE_JIT_I386 # define MZ_JIT_USE_MPROTECT #endif diff --git a/racket/src/racket/sgc/autostat.inc b/racket/src/racket/sgc/autostat.inc index b5eb00dfdc..057545b24b 100644 --- a/racket/src/racket/sgc/autostat.inc +++ b/racket/src/racket/sgc/autostat.inc @@ -14,7 +14,7 @@ # define USE_DATASTARTEND 1 #endif -#if defined(linux) && defined(i386) && defined(__ELF__) +#if defined(__linux) && defined(__i386__) && defined(__ELF__) # include # include # if LINUX_VERSION_CODE >= 0x20000 && defined(__GLIBC__) && __GLIBC__ >= 2 diff --git a/racket/src/racket/src/future.c b/racket/src/racket/src/future.c index 6a31e5aae0..ba46ad5222 100644 --- a/racket/src/racket/src/future.c +++ b/racket/src/racket/src/future.c @@ -2168,7 +2168,7 @@ Scheme_Object *touch(int argc, Scheme_Object *argv[]) } } -#if defined(linux) || defined(__QNX__) +#if defined(__linux__) || defined(__QNX__) # include #elif defined(OS_X) # include @@ -2180,7 +2180,7 @@ Scheme_Object *touch(int argc, Scheme_Object *argv[]) static void init_cpucount(void) /* Called in runtime thread */ { -#if defined(linux) || defined(__QNX__) +#if defined(__linux__) || defined(__QNX__) cpucount = sysconf(_SC_NPROCESSORS_ONLN); #elif defined(OS_X) size_t size = sizeof(cpucount); diff --git a/racket/src/racket/src/unwind/libunwind.h b/racket/src/racket/src/unwind/libunwind.h index 1b4ec2e7d4..735f78307d 100644 --- a/racket/src/racket/src/unwind/libunwind.h +++ b/racket/src/racket/src/unwind/libunwind.h @@ -26,10 +26,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef LIBUNWIND_H #define LIBUNWIND_H -#if defined(linux) +#if defined(__linux__) # define LINUX #endif -#if defined(i386) +#if defined(__i386__) # define PLAIN_X86 #endif #if defined(__x86_64__) From de2722363565b984611d9812d0942e74fb41d3fd Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 8 Oct 2015 17:35:07 -0400 Subject: [PATCH 306/381] Add a quiet mode to the pkg tests. --- pkgs/racket-test/tests/pkg/shelly.rkt | 43 +++++++----- pkgs/racket-test/tests/pkg/test.rkt | 67 +++++++++++-------- .../racket-test/tests/pkg/tests-conflicts.rkt | 3 +- pkgs/racket-test/tests/pkg/util.rkt | 19 ++++-- 4 files changed, 80 insertions(+), 52 deletions(-) diff --git a/pkgs/racket-test/tests/pkg/shelly.rkt b/pkgs/racket-test/tests/pkg/shelly.rkt index ba1c56f5de..0b2f93bd6e 100644 --- a/pkgs/racket-test/tests/pkg/shelly.rkt +++ b/pkgs/racket-test/tests/pkg/shelly.rkt @@ -6,9 +6,14 @@ (for-syntax racket/base syntax/parse)) + ;; {{ Shelly ;; This macro is intended to make Eli proud. +;; Do we print a lot of output? +(define verbose? (make-parameter #t)) +(provide verbose?) + ;; Wow, RackUnit really sucks that test-begin/case don't work inside ;; each other like this already. We Want's RackUnit's detailed printing ;; of test failure, but not it's throw-away-the-exception behavior: @@ -57,7 +62,8 @@ cmd (define output-port (open-output-string)) (define error-port (open-output-string)) - (printf "$ ~a\n" cmd) + (when (verbose?) + (printf "$ ~a\n" cmd)) (match-define (list stdout stdin pid stderr to-proc) (process/ports #f @@ -67,23 +73,26 @@ cmd)) (define stdout-t (thread - (λ () - (with-handlers ([exn:input-port-closed? void]) - (copy-port stdout output-port - (current-output-port)))))) + (λ () + (with-handlers ([exn:input-port-closed? void]) + (if (verbose?) + (copy-port stdout output-port + (current-output-port)) + (copy-port stdout output-port)))))) (define stderr-t (thread (λ () - (with-handlers ([exn:input-port-closed? void]) - (define cop (current-output-port)) - (let loop () - (define l (read-bytes-line stderr)) - (unless (eof-object? l) - (displayln l error-port) - (displayln (format "STDERR: ~a" l) cop) - (flush-output error-port) - (flush-output cop) - (loop))))))) + (with-handlers ([exn:input-port-closed? void]) + (define cop (current-output-port)) + (let loop () + (define l (read-bytes-line stderr)) + (unless (eof-object? l) + (displayln l error-port) + (when (verbose?) + (displayln (format "STDERR: ~a" l) cop) + (flush-output cop)) + (flush-output error-port) + (loop))))))) (to-proc 'wait) (define cmd-status (to-proc 'exit-code)) (when stdin (close-output-port stdin)) @@ -119,9 +128,9 @@ (let () (define mv m) (check-case mv - (printf "# Starting... ~a\n" mv) + (when (verbose?) (printf "# Starting... ~a\n" mv)) case.code ... - (printf "# Ending... ~a\n" mv))))])) + (when (verbose?) (printf "# Ending... ~a\n" mv)))))])) (define-syntax (shelly-wind stx) (syntax-parse stx diff --git a/pkgs/racket-test/tests/pkg/test.rkt b/pkgs/racket-test/tests/pkg/test.rkt index d4e222c558..42b0801335 100644 --- a/pkgs/racket-test/tests/pkg/test.rkt +++ b/pkgs/racket-test/tests/pkg/test.rkt @@ -29,35 +29,46 @@ (shelly-case "All tests" (for-each (λ (x) (x)) l))))) -(run-tests - "name" - "basic" "create" "install" "permissions" - "conflicts" "checksums" - "deps" "update" "implies" - "remove" - "promote" - "locking" - "overwrite" - "config" - "clone" - "catalog-links" - - "network" - "planet" - "main-server" +(define (go) + (run-tests + "name" + "basic" "create" "install" "permissions" + "conflicts" "checksums" + "deps" "update" "implies" + "remove" + "promote" + "locking" + "overwrite" + "config" + "clone" + "catalog-links" - "update-deps" - "update-auto" - "scope" - "trash" - "migrate" - "versions" - "platform" - "raco" - "binary" - "catalogs" - "failure") + "network" + "planet" + "main-server" + + "update-deps" + "update-auto" + "scope" + "trash" + "migrate" + "versions" + "platform" + "raco" + "binary" + "catalogs" + "failure")) (module+ test (module config info - (define timeout 2400))) + (define timeout 2400)) + (go)) + +(module+ main + (require racket/cmdline) + (define quiet? #f) + (command-line + #:once-each + ["-q" "run quietly" (set! quiet? #t)] + #:args () + (parameterize ([verbose? (not quiet?)]) (go)))) diff --git a/pkgs/racket-test/tests/pkg/tests-conflicts.rkt b/pkgs/racket-test/tests/pkg/tests-conflicts.rkt index f5993d1228..94e7b6d9e9 100644 --- a/pkgs/racket-test/tests/pkg/tests-conflicts.rkt +++ b/pkgs/racket-test/tests/pkg/tests-conflicts.rkt @@ -226,7 +226,8 @@ (for* ([m1 '(src both zo-stays zo-goes)] [m2 '(src both zo-stays zo-goes)]) - (printf "trying ~s ~s\n" m1 m2) + (when (verbose?) + (printf "trying ~s ~s\n" m1 m2)) (set-conflict-mode t1-nc1-dir m1) (set-conflict-mode t1-nc2-dir m2) (if (and (eq? m1 'zo-goes) (eq? m2 'zo-goes)) diff --git a/pkgs/racket-test/tests/pkg/util.rkt b/pkgs/racket-test/tests/pkg/util.rkt index 83af634585..944b274b32 100644 --- a/pkgs/racket-test/tests/pkg/util.rkt +++ b/pkgs/racket-test/tests/pkg/util.rkt @@ -9,6 +9,7 @@ racket/path racket/list racket/format + racket/port setup/dirs "shelly.rkt") @@ -111,20 +112,26 @@ (require web-server/http web-server/servlet-env) (define (start-file-server) - (serve/servlet (λ (req) (response/xexpr "None")) - #:command-line? #t - #:port 9997 - #:extra-files-paths (list (build-path test-directory "test-pkgs")))) + (parameterize ([current-error-port (if (verbose?) + (current-output-port) + (open-output-nowhere))]) + (serve/servlet (λ (req) (response/xexpr "None")) + #:command-line? #t + #:port 9997 + #:extra-files-paths (list (build-path test-directory "test-pkgs"))))) (require "basic-index.rkt") (define *index-ht-1* (make-hash)) (define *index-ht-2* (make-hash)) (define (start-pkg-server index-ht port) - (parameterize ([current-error-port (current-output-port)]) + (parameterize ([current-error-port (if (verbose?) + (current-output-port) + (open-output-nowhere))]) (serve/servlet (pkg-index/basic (λ (pkg-name) (define r (hash-ref index-ht pkg-name #f)) - (printf "[>server ~a] ~a = ~a\n" port pkg-name r) + (when (verbose?) + (printf "[>server ~a] ~a = ~a\n" port pkg-name r)) r) (λ () index-ht)) #:command-line? #t From 6b0e3f2aeb4c42eb533d8d4a7f6b05c8fd3b101a Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Fri, 11 Sep 2015 21:28:55 -0400 Subject: [PATCH 307/381] Run the pkg tests on Travis. - Add indirectly-missing dep for pkg tests. - Configure git on Travis to help pkg tests. --- .travis.yml | 4 ++++ pkgs/racket-test/info.rkt | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6982e877f7..69b233f44b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,9 +25,13 @@ matrix: compiler: gcc env: PATH=./racket/bin:$PATH RACKET_CONFIGURE_ARGS="--disable-jit --disable-places --disable-futures --disable-extflonum" +before_script: +- git config --global user.email "travis-test@racket-lang.org" +- git config --global user.name "Travis Tester" script: - make CPUS="2" PKGS="racket-test db-test unstable-flonum-lib net-test" CONFIGURE_ARGS_qq="$RACKET_CONFIGURE_ARGS" - raco test -l tests/racket/test +- racket -l tests/pkg/test -- -q - racket -l tests/racket/contract/all - raco test -l tests/json/json - raco test -l tests/file/main diff --git a/pkgs/racket-test/info.rkt b/pkgs/racket-test/info.rkt index 1ebe644ba7..ca298ea7c7 100644 --- a/pkgs/racket-test/info.rkt +++ b/pkgs/racket-test/info.rkt @@ -8,7 +8,7 @@ "planet-lib" "net-lib" "net-test" ; for tests/net/available - "serialize-cstruct-lib" ; tested here + "serialize-cstruct-lib" ; tested here "cext-lib" ; tested here "pconvert-lib" ; tested here @@ -22,6 +22,9 @@ ;; for `json` tests "at-exp-lib" + ;; used by the planet packages tested by the pkg tests + "srfi-lib" + ;; used to test setup, module readers, pkg system "scribble-lib")) From aa7c3ac38b75aa96bd146f828a8b0b367b6d1331 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 8 Oct 2015 18:15:06 -0600 Subject: [PATCH 308/381] use libtool `install -s` to install libraries Use `install -s` instead of `strip -S` when building shared libraries via libtool. --- racket/src/configure | 5 +++++ racket/src/racket/Makefile.in | 7 ++++--- racket/src/racket/configure.ac | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/racket/src/configure b/racket/src/configure index 6415cd57ca..87f48a7c2c 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -672,6 +672,7 @@ MAKE_COPYTREE MAKE_GRACKET LIBFINISH MRLIBINSTALL +ICP_LIB ICP WXVARIANT WXLIBS @@ -6765,6 +6766,7 @@ if test "${enable_shared}" = "yes" ; then LIBSFX=la WXLIBS=WXLIBSDYN ICP="${LIBTOOLPROG} --mode=install cp" + ICP_LIB="${LIBTOOLPROG} --mode=install install -s" MRLIBINSTALL="install-lib" LIBFINISH="${LIBTOOLPROG} --mode=finish" LTO="lo" @@ -6772,10 +6774,12 @@ if test "${enable_shared}" = "yes" ; then FOREIGN_CONVENIENCE="_convenience" FOREIGN_OBJSLIB="\$(FOREIGN_LIB)" MZOPTIONS="$MZOPTIONS -DMZ_USES_SHARED_LIB" + STRIP_LIB_DEBUG=":" else LIBSFX=a WXLIBS=WXLIBSNORM ICP=cp + ICP_LIB=cp MRLIBINSTALL="install-no-lib" LIBFINISH=echo LTO="o" @@ -6910,6 +6914,7 @@ LIBS="$LIBS $EXTRALIBS" + mk_needed_dir() diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 2d8e4c750d..78935c77d0 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -354,6 +354,7 @@ clean@OSX@: BUILDINFO=$(DESTDIR)$(libpltdir)/buildinfo ICP=@ICP@ +ICP_LIB=@ICP_LIB@ install: $(MAKE) install-@MAIN_VARIANT@ @@ -405,8 +406,8 @@ unix-install-cgc: @RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@@EXE_SUFFIX@" $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ unix-install-libs-cgc: - cd ..; $(ICP) racket/libmzgc.@LIBSFX@ "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" - cd ..; $(ICP) racket/libracket.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" + cd ..; $(ICP_LIB) racket/libmzgc.@LIBSFX@ "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" + cd ..; $(ICP_LIB) racket/libracket.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" cd ..; $(STRIP_LIB_DEBUG) "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@" cd ..; $(STRIP_LIB_DEBUG) "$(DESTDIR)$(libdir)/libracket.@LIBSFX@" @@ -424,7 +425,7 @@ unix-install-3m: @RUN_RACKET_MMM@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)$(bindir)/racket@MMM_INSTALLED@@EXE_SUFFIX@" $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@ unix-install-libs-3m: - cd ..; $(ICP) racket/libracket3m.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" + cd ..; $(ICP_LIB) racket/libracket3m.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" cd ..; $(STRIP_LIB_DEBUG) "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@" unix-no-install-libs-3m: diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index aea5974d24..d778329f93 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -1669,6 +1669,7 @@ if test "${enable_shared}" = "yes" ; then LIBSFX=la WXLIBS=WXLIBSDYN ICP="${LIBTOOLPROG} --mode=install cp" + ICP_LIB="${LIBTOOLPROG} --mode=install install -s" MRLIBINSTALL="install-lib" LIBFINISH="${LIBTOOLPROG} --mode=finish" LTO="lo" @@ -1676,10 +1677,12 @@ if test "${enable_shared}" = "yes" ; then FOREIGN_CONVENIENCE="_convenience" FOREIGN_OBJSLIB="\$(FOREIGN_LIB)" MZOPTIONS="$MZOPTIONS -DMZ_USES_SHARED_LIB" + STRIP_LIB_DEBUG=":" else LIBSFX=a WXLIBS=WXLIBSNORM ICP=cp + ICP_LIB=cp MRLIBINSTALL="install-no-lib" LIBFINISH=echo LTO="o" @@ -1753,6 +1756,7 @@ AC_SUBST(LIBSFX) AC_SUBST(WXLIBS) AC_SUBST(WXVARIANT) AC_SUBST(ICP) +AC_SUBST(ICP_LIB) AC_SUBST(MRLIBINSTALL) AC_SUBST(LIBFINISH) From a2b213ad1bc4701dcfcd157a8117ff7fa672b6ed Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 6 Oct 2015 20:52:22 +0200 Subject: [PATCH 309/381] Fix typos --- pkgs/racket-doc/scribblings/guide/unit.scrbl | 2 +- pkgs/racket-doc/scribblings/guide/welcome.scrbl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-doc/scribblings/guide/unit.scrbl b/pkgs/racket-doc/scribblings/guide/unit.scrbl index c345b231d5..63705e427d 100644 --- a/pkgs/racket-doc/scribblings/guide/unit.scrbl +++ b/pkgs/racket-doc/scribblings/guide/unit.scrbl @@ -603,7 +603,7 @@ As a form for modularity, @racket[unit] complements @racket[module]: ] The @racket[lambda] and @racket[class] forms, among others, also allow -paremetrization of code with respect to values that are chosen +parameterization of code with respect to values that are chosen later. In principle, any of those could be implemented in terms of any of the others. In practice, each form offers certain conveniences---such as allowing overriding of methods or especially diff --git a/pkgs/racket-doc/scribblings/guide/welcome.scrbl b/pkgs/racket-doc/scribblings/guide/welcome.scrbl index a5fab120c0..b6d1e96a45 100644 --- a/pkgs/racket-doc/scribblings/guide/welcome.scrbl +++ b/pkgs/racket-doc/scribblings/guide/welcome.scrbl @@ -204,7 +204,7 @@ To package the program as an executable, you have a few options: @; ---------------------------------------------------------------------- @section[#:tag "use-module"]{A Note to Readers with Lisp/Scheme Experience} -If you already know something about Racket or Lisp, you might be +If you already know something about Scheme or Lisp, you might be tempted to put just @racketblock[ From a6835422bfd8984bf078f5fd3f9e3af90969296a Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 9 Oct 2015 15:23:31 -0400 Subject: [PATCH 310/381] Post-release version for the v6.3 release --- pkgs/base/info.rkt | 2 +- racket/src/racket/src/schvers.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index 84ea116d61..c85728fa02 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.2.900.17") +(define version "6.3.0.1") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 5aec9b8b28..6ff9efb9ef 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.2.900.17" +#define MZSCHEME_VERSION "6.3.0.1" #define MZSCHEME_VERSION_X 6 -#define MZSCHEME_VERSION_Y 2 -#define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 17 +#define MZSCHEME_VERSION_Y 3 +#define MZSCHEME_VERSION_Z 0 +#define MZSCHEME_VERSION_W 1 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 6c0ffe1ba26adbabe581284ef6a372a5bc9726c2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 11 Oct 2015 07:38:54 -0600 Subject: [PATCH 311/381] add missing `history` Merge to v6.3 --- pkgs/racket-doc/scribblings/reference/exns.scrbl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/racket-doc/scribblings/reference/exns.scrbl b/pkgs/racket-doc/scribblings/reference/exns.scrbl index ea26cdbddc..9b43d8b07e 100644 --- a/pkgs/racket-doc/scribblings/reference/exns.scrbl +++ b/pkgs/racket-doc/scribblings/reference/exns.scrbl @@ -966,6 +966,8 @@ Returns the @tech{module path}-getting procedure associated with @racket[v].} @note-lib-only[racket/exn] +@history[#:added "6.3"] + @defproc[(exn->string [exn (or/c exn? any/c)]) string?]{ Formats @racket[exn] as a string. If @racket[exn] is an @racket[exn?], From 5afdae8af9ad1e4dea484fb6b2db3b3c930fb024 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 12 Oct 2015 08:30:47 -0600 Subject: [PATCH 312/381] net/url-string: change parsing of "file:" URLs for Windows History of the parsing of "file:" URLs for Windows: * In response to PR 8060 (April 2006): special handling added to support ill-formed URLs that were (are?) commonly used for filesystem paths. * Follow-up to PR 8060 (April 2008): added `path->url` and `url->path`. * In response to #1086 (October 2015, the commit): changed Windows-specific handling to be more constrained and added support for the proper encoding of UNC paths --- where "proper" means "according to a blog post from late 2006", which appears to be as close as we get to documentation of the URL encoding for Windows paths. --- racket/collects/net/url-string.rkt | 52 ++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/racket/collects/net/url-string.rkt b/racket/collects/net/url-string.rkt index 77cb5560e4..5febeaf4e3 100644 --- a/racket/collects/net/url-string.rkt +++ b/racket/collects/net/url-string.rkt @@ -200,24 +200,30 @@ (url-error "Invalid URL string; bad scheme ~e: ~e" scheme str)) ;; Windows => "file://xxx:/...." specifies a "xxx:/..." path (let ([win-file? (and (or (equal? "" port) (not port)) - (equal? "file" scheme) + (equal? "file" (and scheme (string-downcase scheme))) (eq? 'windows (file-url-path-convention-type)) - (not (equal? host "")))]) + (not (equal? host "")) + (or (regexp-match? "^[fF][iI][lL][eE]://[a-zA-Z]:" str) + (regexp-match? "^[fF][iI][lL][eE]:\\\\" str)))]) (when win-file? (set! path (cond [(equal? "" port) (string-append host ":" path)] [(and path host) (string-append host "/" path)] [else (or path host)])) (set! port #f) (set! host "")) + (define win-file-url (and win-file? + (path->url (bytes->path (string->bytes/utf-8 path) 'windows)))) (let* ([scheme (and scheme (string-downcase scheme))] - [host (and host (string-downcase host))] + [host (if win-file-url + (url-host win-file-url) + (and host (string-downcase host)))] [user (uri-decode/maybe user)] [port (and port (string->number port))] [abs? (or (equal? "file" scheme) (regexp-match? #rx"^/" path))] [path (if win-file? - (separate-windows-path-strings path) - (separate-path-strings path))] + (url-path win-file-url) + (separate-path-strings path))] [query (if query (form-urlencoded->alist query) '())] [fragment (uri-decode/maybe fragment)]) (make-url scheme user host port abs? path query fragment)))) @@ -236,9 +242,6 @@ (let ([strs (regexp-split #rx"/" str)]) (map separate-params (if (string=? "" (car strs)) (cdr strs) strs)))) -(define (separate-windows-path-strings str) - (url-path (path->url (bytes->path (string->bytes/utf-8 str) 'windows)))) - (define (separate-params s) (let ([lst (map path-segment-decode (regexp-split #rx";" s))]) (make-path/param (car lst) (cdr lst)))) @@ -273,7 +276,7 @@ ;; If original path is a directory the resulting URL ;; should have a trailing forward slash [url-tail (if dir? (list (make-path/param "" null)) null)] - [url-path + [host+url-path (let loop ([path spath][accum null]) (let-values ([(base name dir?) (split-path path)]) (cond @@ -290,18 +293,18 @@ (cond [(regexp-match? #rx"^\\\\\\\\[?]\\\\[a-zA-Z]:" s) ;; \\?\: path: - (regexp-split #rx"[/\\]+" (substring s 4))] + (cons "" (regexp-split #rx"[/\\]+" (substring s 4)))] [(regexp-match? #rx"^\\\\\\\\[?]\\\\UNC" s) ;; \\?\ UNC path: - (regexp-split #rx"[/\\]+" (substring s 7))] + (cons "" (regexp-split #rx"[/\\]+" (substring s 7)))] [(regexp-match? #rx"^[/\\]" s) ;; UNC path: - (regexp-split #rx"[/\\]+" s)] + (cdr (regexp-split #rx"[/\\]+" s))] [else - (list s)]))) + (list "" s)]))) accum) ;; On other platforms, we drop the root: - accum)] + (cons "" accum))] [else (let ([accum (cons (make-path/param (if (symbol? name) @@ -311,9 +314,14 @@ null) accum)]) (if (eq? base 'relative) - accum - (loop base accum)))])))]) - (make-url "file" #f "" #f (absolute-path? path) + (cons "" accum) + (loop base accum)))])))] + [host (let ([h (car host+url-path)]) + (if (path/param? h) + (path/param-path h) + h))] + [url-path (cdr host+url-path)]) + (make-url "file" #f host #f (absolute-path? path) (if (null? url-tail) url-path (append url-path url-tail)) '() #f))) @@ -331,6 +339,7 @@ (if (and (url-path-absolute? url) (eq? 'windows kind)) ;; If initial path is "", then build UNC path. + ;; Also build a UNC path if the host is non-#f. (cond [(not (url-path-absolute? url)) (apply build-path (map string->path-element/same strs))] @@ -340,6 +349,15 @@ (string->path/win (string-append "\\\\" (cadr strs) "\\" (caddr strs) "\\")) (map string->path-element/same (cdddr strs)))] + [(and (url-host url) + (not (equal? (url-host url) "")) + (pair? strs)) + (if (equal? (car strs) "") + (error 'file://->path "rmpty drive element: ~e" url) + (apply build-path + (string->path/win + (string-append "\\\\" (url-host url) "\\" (car strs) "\\")) + (map string->path-element/same (cdr strs))))] [(pair? strs) (apply build-path (string->path/win (car strs)) (map string->path-element/same (cdr strs)))] From 270bbccf6b862721764aa77ddeac81bf62da2aeb Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 12 Oct 2015 13:49:47 -0500 Subject: [PATCH 313/381] Fix history annotations to refer to 6.3. Please merge to 6.3. --- pkgs/racket-doc/file/scribblings/ico.scrbl | 8 ++++---- pkgs/racket-doc/file/scribblings/untar.scrbl | 2 +- pkgs/racket-doc/file/scribblings/untgz.scrbl | 2 +- pkgs/racket-doc/file/scribblings/unzip.scrbl | 2 +- pkgs/racket-doc/pkg/scribblings/lib.scrbl | 2 +- pkgs/racket-doc/pkg/scribblings/pkg.scrbl | 4 ++-- pkgs/racket-doc/scribblings/foreign/objc.scrbl | 10 +++++----- pkgs/racket-doc/scribblings/raco/api.scrbl | 4 ++-- pkgs/racket-doc/scribblings/raco/dist-api.scrbl | 2 +- pkgs/racket-doc/scribblings/raco/exe-api.scrbl | 4 ++-- pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl | 2 +- pkgs/racket-doc/scribblings/raco/make.scrbl | 2 +- pkgs/racket-doc/scribblings/raco/setup.scrbl | 6 +++--- pkgs/racket-doc/scribblings/reference/contracts.scrbl | 8 ++++---- pkgs/racket-doc/scribblings/reference/eval.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/filesystem.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/hashes.scrbl | 4 ++-- pkgs/racket-doc/scribblings/reference/logging.scrbl | 6 +++--- pkgs/racket-doc/scribblings/reference/memory.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/numbers.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/os-lib.scrbl | 2 +- .../scribblings/reference/pretty-print.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/promise.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/sequences.scrbl | 4 ++-- pkgs/racket-doc/scribblings/reference/strings.scrbl | 4 ++-- pkgs/racket-doc/scribblings/reference/stx-trans.scrbl | 4 ++-- pkgs/racket-doc/syntax/scribblings/contract.scrbl | 2 +- pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl | 2 +- pkgs/racket-doc/syntax/scribblings/module-reader.scrbl | 2 +- 29 files changed, 50 insertions(+), 50 deletions(-) diff --git a/pkgs/racket-doc/file/scribblings/ico.scrbl b/pkgs/racket-doc/file/scribblings/ico.scrbl index f69335df06..7dcabefb86 100644 --- a/pkgs/racket-doc/file/scribblings/ico.scrbl +++ b/pkgs/racket-doc/file/scribblings/ico.scrbl @@ -27,7 +27,7 @@ otherwise.} Returns the width or height of an icon in pixels, or the depth in bits per pixel. -@history[#:changed "6.2.900.10" @elem{A PNG-format icon can have a +@history[#:changed "6.3" @elem{A PNG-format icon can have a width or height greater than 256.}]} @@ -37,7 +37,7 @@ pixel. Reports the format of the icon. -@history[#:added "6.2.900.10"]} +@history[#:added "6.3"]} @defproc[(read-icos [src (or/c path-string? input-port?)]) @@ -103,7 +103,7 @@ green, and blue channels) for each pixel.} Returns the bytes of a PNG encoding for an icon in PNG format (see @racket[ico-format]). -@history[#:added "6.2.900.10"]} +@history[#:added "6.3"]} @defproc[(argb->ico [width (integer-in 1 256)] @@ -125,4 +125,4 @@ and @racket[(* width depth)] must be a multiple of 8.} Wraps the given PNG encoding as a PNG-encoded icon. -@history[#:added "6.2.900.10"]} +@history[#:added "6.3"]} diff --git a/pkgs/racket-doc/file/scribblings/untar.scrbl b/pkgs/racket-doc/file/scribblings/untar.scrbl index 7987015795..e8d6671a62 100644 --- a/pkgs/racket-doc/file/scribblings/untar.scrbl +++ b/pkgs/racket-doc/file/scribblings/untar.scrbl @@ -69,4 +69,4 @@ For each item in the archive, @racket[filter-proc] is applied to If the result of @racket[filter-proc] is @racket[#f], then the item is not unpacked. -@history[#:changed "6.2.900.17" @elem{Added the @racket[#:permissive?] argument.}]} +@history[#:changed "6.3" @elem{Added the @racket[#:permissive?] argument.}]} diff --git a/pkgs/racket-doc/file/scribblings/untgz.scrbl b/pkgs/racket-doc/file/scribblings/untgz.scrbl index 479865af2e..433baac749 100644 --- a/pkgs/racket-doc/file/scribblings/untgz.scrbl +++ b/pkgs/racket-doc/file/scribblings/untgz.scrbl @@ -24,4 +24,4 @@ a function to extract items from a possible @exec{gzip}ped TAR/USTAR archive.} The same as @racket[untar], but if @racket[in] is in @exec{gzip} form, it is @racket[gunzip]ped as it is unpacked. -@history[#:changed "6.2.900.17" @elem{Added the @racket[#:permissive?] argument.}]} +@history[#:changed "6.3" @elem{Added the @racket[#:permissive?] argument.}]} diff --git a/pkgs/racket-doc/file/scribblings/unzip.scrbl b/pkgs/racket-doc/file/scribblings/unzip.scrbl index d3c619c8af..8e574ed4e0 100644 --- a/pkgs/racket-doc/file/scribblings/unzip.scrbl +++ b/pkgs/racket-doc/file/scribblings/unzip.scrbl @@ -86,7 +86,7 @@ inflated content. @history[#:changed "6.0.0.3" @elem{Added support for the optional timestamp argument in the result function.} - #:changed "6.2.900.17" + #:changed "6.3" @elem{Added the @racket[#:permissive?] argument.}]} diff --git a/pkgs/racket-doc/pkg/scribblings/lib.scrbl b/pkgs/racket-doc/pkg/scribblings/lib.scrbl index b32916016b..f582239550 100644 --- a/pkgs/racket-doc/pkg/scribblings/lib.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/lib.scrbl @@ -112,7 +112,7 @@ that fails due to a connection error. If a parameter's value is @racket[#f], then the user's configuration is used. -@history[#:added "6.2.900.17"]} +@history[#:added "6.3"]} @defproc[(pkg-directory [name string?] diff --git a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl index 4f58014a23..d21a87beef 100644 --- a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -310,7 +310,7 @@ If the @indexed-envvar{PLT_USE_GITHUB_API} environment variable is set, GitHub packages are obtained using the GitHub API protocol instead of using the Git protocol. -@history[#:changed "6.2.900.16" @elem{Changed handling of +@history[#:changed "6.3" @elem{Changed handling of GitHub sources to use the Git protocol by default.}]} @@ -945,7 +945,7 @@ for @nonterm{key}. ] @history[#:changed "6.1.1.6" @elem{Added @exec{trash-max-packages} and @exec{trash-max-seconds}.} - #:changed "6.2.900.17" @elem{Added @exec{network-retries}.}]} + #:changed "6.3" @elem{Added @exec{network-retries}.}]} @subcommand{@command/toc{catalog-show} @nonterm{option} ... @nonterm{package-name} ... diff --git a/pkgs/racket-doc/scribblings/foreign/objc.scrbl b/pkgs/racket-doc/scribblings/foreign/objc.scrbl index 6a52571c9d..e865eda59b 100644 --- a/pkgs/racket-doc/scribblings/foreign/objc.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/objc.scrbl @@ -274,7 +274,7 @@ Check whether @racket[subcls] is @racket[cls] or a subclass. Extract the class of @racket[obj]. -@history[#:added "6.2.900.14"]} +@history[#:added "6.3"]} @defproc[(objc-set-class! [obj _id] [cls _Class]) void?]{ @@ -282,14 +282,14 @@ Extract the class of @racket[obj]. Changes the class of @racket[obj] to @racket[cls]. The object's existing representation must be compatible with the new class. -@history[#:added "6.2.900.14"]} +@history[#:added "6.3"]} @defproc[(objc-get-superclass [cls _Class]) _Class]{ Returns the superclass of @racket[cls]. -@history[#:added "6.2.900.14"]} +@history[#:added "6.3"]} @defproc[(objc-dispose-class [cls _Class]) void?]{ @@ -297,7 +297,7 @@ Returns the superclass of @racket[cls]. Destroys @racket[cls], which must have no existing instances or subclasses. -@history[#:added "6.2.900.14"]} +@history[#:added "6.3"]} @defproc[(objc-block [function-type? ctype] @@ -316,7 +316,7 @@ the list in @racket[keep], which might also be included in @racket[_fun]. The pointers registered in @racket[keep] must be retained as long as the block remains in use. -@history[#:added "6.2.900.14"]} +@history[#:added "6.3"]} @; ---------------------------------------------------------------------- diff --git a/pkgs/racket-doc/scribblings/raco/api.scrbl b/pkgs/racket-doc/scribblings/raco/api.scrbl index 0469e07eed..fbb00f3afb 100644 --- a/pkgs/racket-doc/scribblings/raco/api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/api.scrbl @@ -138,7 +138,7 @@ collection. The following fields are used: ] -@history[#:changed "6.2.900.10" @elem{Added support for @racket[compile-include-files].}]} +@history[#:changed "6.3" @elem{Added support for @racket[compile-include-files].}]} @defproc[(compile-directory-zos [path path-string?] @@ -169,7 +169,7 @@ a directory, and so on. The set of suffixes always includes @filepath{.rkt}, @filepath{.ss}, and @filepath{.scm}, but it can be extended globally by @filepath{info.rkt} configuration in collections.} -@history[#:added "6.2.900.10"] +@history[#:added "6.3"] @defproc[(get-module-suffixes [#:group group (or/c 'all 'libs 'docs) 'all] [#:mode mode (or/c 'preferred 'all-available 'no-planet 'no-user) 'preferred] diff --git a/pkgs/racket-doc/scribblings/raco/dist-api.scrbl b/pkgs/racket-doc/scribblings/raco/dist-api.scrbl index a650feb02b..7f6676c99e 100644 --- a/pkgs/racket-doc/scribblings/raco/dist-api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/dist-api.scrbl @@ -46,5 +46,5 @@ The content of each directory in the @racket[#:copy-collects] argument is copied into the main @filepath{collects} directory for the packaged executables. -@history[#:changed "6.2.900.17" @elem{Added the @racket[#:executables?] +@history[#:changed "6.3" @elem{Added the @racket[#:executables?] and @racket[#:relative-base] arguments.}]} diff --git a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl index f469bdd625..24b5c9183e 100644 --- a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl @@ -189,7 +189,7 @@ currently supported keys are as follows: @item{@racket['ico] (Windows) : An icon file path (suffix @filepath{.ico}) to use for the executable's desktop icon. - @history[#:changed "6.2.900.10" @elem{All icons in the + @history[#:changed "6.3" @elem{All icons in the executable are replaced with icons from the file, instead of setting only certain sizes and depths.}]} @@ -486,4 +486,4 @@ A unit that imports nothing and exports @racket[compiler:embed^].} If @racket[cross?] is true, the executable is found for the target platform in @seclink["cross-system"]{cross-installation mode}. - @history[#:changed "6.2.900.11" @elem{Added the @racket[#:cross?] argument.}]} + @history[#:changed "6.3" @elem{Added the @racket[#:cross?] argument.}]} diff --git a/pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl b/pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl index 1b223ff401..947d3e33bd 100644 --- a/pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl +++ b/pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl @@ -11,7 +11,7 @@ reading and adjusting dynamic-library references in a Mac OS X executable.} -@history[#:added "6.2.900.9"] +@history[#:added "6.3"] @defproc[(find-matching-library-path [exe-path path-string?] [library-str string?]) diff --git a/pkgs/racket-doc/scribblings/raco/make.scrbl b/pkgs/racket-doc/scribblings/raco/make.scrbl index 4e5d4af085..cb83f404bf 100644 --- a/pkgs/racket-doc/scribblings/raco/make.scrbl +++ b/pkgs/racket-doc/scribblings/raco/make.scrbl @@ -508,7 +508,7 @@ submodules within the region. The existing representation should have zero bytes in place of each hash string, which is what @racket[write] produces for a compiled form. -@history[#:added "6.2.900.8"]} +@history[#:added "6.3"]} @; ---------------------------------------------------------------------- diff --git a/pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-doc/scribblings/raco/setup.scrbl index 58d6b50d9f..7a4340a9b0 100644 --- a/pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -1730,7 +1730,7 @@ or @litchar{_}.} @defmodule[setup/collection-search] -@history[#:added "6.2.900.6"] +@history[#:added "6.3"] @defproc[(collection-search [mod-path normalized-lib-module-path?] [#:init result any/c #f] @@ -1808,7 +1808,7 @@ If @racket[spec] is a regexp value, then the result is @racket[#t] if the regexp matches @racket[(path->string sys-lib-subpath)], @racket[#f] otherwise. -@history[#:changed "6.2.900.11" @elem{Added @racket[#:cross?] argument and +@history[#:changed "6.3" @elem{Added @racket[#:cross?] argument and changed the contract on @racket[sys-lib-subpath] to accept @racket[path-for-some-system?] instead of just @racket[path?].}]} @@ -1841,7 +1841,7 @@ libraries need to run to perform the requested @exec{raco pkg} action (e.g., when installing built packages). -@history[#:added "6.2.900.11"] +@history[#:added "6.3"] @defproc[(cross-system-type [mode (or/c 'os 'word 'gc 'link 'machine 'so-suffix 'so-mode 'fs-change) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index e75547f03f..6360ea9e34 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -198,7 +198,7 @@ second. If all of its arguments are @racket[list-contract?]s, then @racket[or/c] returns a @racket[list-contract?]. -@history[#:changed "6.2.900.17" @list{Adjusted @racket[or/c] so that it +@history[#:changed "6.3" @list{Adjusted @racket[or/c] so that it takes the first higher-order contract instead of insisting that there be exactly one higher-order contract for a given value.}] } @@ -2832,7 +2832,7 @@ currently being checked. The resulting contract is a flat contract if @racket[contract] is a flat contract. - @history[#:added "6.2.900.15"] + @history[#:added "6.3"] } @defproc[(if/c [predicate (-> any/c any/c)] @@ -2855,7 +2855,7 @@ currently being checked. The last contract is the same as @racket[any/c] because @racket[or/c] tries flat contracts before higher-order contracts. - @history[#:added "6.2.900.15"] + @history[#:added "6.3"] } @defthing[failure-result/c contract?]{ @@ -2864,7 +2864,7 @@ currently being checked. Equivalent to @racket[(if/c procedure? (-> any) any/c)]. - @history[#:added "6.2.900.15"] + @history[#:added "6.3"] } diff --git a/pkgs/racket-doc/scribblings/reference/eval.scrbl b/pkgs/racket-doc/scribblings/reference/eval.scrbl index 4b37eea3e1..48964f5a7b 100644 --- a/pkgs/racket-doc/scribblings/reference/eval.scrbl +++ b/pkgs/racket-doc/scribblings/reference/eval.scrbl @@ -493,7 +493,7 @@ performance characteristics. If @racket[ce] includes module forms, then only phase-0 code in the immediate module (not in submodules) is recompiled. -@history[#:added "6.2.900.9"]} +@history[#:added "6.3"]} @defproc[(compiled-expression? [v any/c]) boolean?]{ diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index d5c4edeb72..8c08380f8a 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -953,7 +953,7 @@ keep only the properties kept by @racket[copy-file]. If @racket[keep-modify-seconds?] is true, then each file copy also keeps the modification date of the original. -@history[#:changed "6.2.900.9" @elem{Added the @racket[#:preserve-links?] argument.}]} +@history[#:changed "6.3" @elem{Added the @racket[#:preserve-links?] argument.}]} @defproc[(delete-directory/files [path path-string?] diff --git a/pkgs/racket-doc/scribblings/reference/hashes.scrbl b/pkgs/racket-doc/scribblings/reference/hashes.scrbl index 1677bd9a43..b5b3421634 100644 --- a/pkgs/racket-doc/scribblings/reference/hashes.scrbl +++ b/pkgs/racket-doc/scribblings/reference/hashes.scrbl @@ -384,7 +384,7 @@ such as when the keys are all symbols and @racket[hash] is not an @see-also-concurrency-caveat[] -@history[#:changed "6.2.900.8" @elem{Added the @racket[try-order?] argument.}]} +@history[#:changed "6.3" @elem{Added the @racket[try-order?] argument.}]} @defproc[(hash-keys [hash hash?]) (listof any/c)]{ @@ -420,7 +420,7 @@ See @racket[hash-map] for information about @racket[try-order?] and about modifying @racket[hash] within @racket[proc]. @see-also-concurrency-caveat[] -@history[#:changed "6.2.900.8" @elem{Added the @racket[try-order?] argument.}]} +@history[#:changed "6.3" @elem{Added the @racket[try-order?] argument.}]} @defproc[(hash-count [hash hash?]) diff --git a/pkgs/racket-doc/scribblings/reference/logging.scrbl b/pkgs/racket-doc/scribblings/reference/logging.scrbl index 7d56320385..170dff5826 100644 --- a/pkgs/racket-doc/scribblings/reference/logging.scrbl +++ b/pkgs/racket-doc/scribblings/reference/logging.scrbl @@ -333,7 +333,7 @@ Returns @racket[#t] if @racket[v] is a valid logging level (@racket['none], @racket['fatal], @racket['error], @racket['warning], @racket['info], or @racket['debug]), @racket[#f] otherwise. -@history[#:added "6.2.900.5"]{} +@history[#:added "6.3"]{} } @defproc[(with-intercepted-logging @@ -368,7 +368,7 @@ Returns whatever @racket[proc] returns. 'warning) warning-counter)] -@history[#:added "6.2.900.5"]{}} +@history[#:added "6.3"]{}} @defproc[(with-logging-to-port [port output-port?] [proc (-> any)] @@ -391,4 +391,4 @@ Returns whatever @racket[proc] returns. 'warning) (get-output-string my-log))] -@history[#:added "6.2.900.5"]{}} +@history[#:added "6.3"]{}} diff --git a/pkgs/racket-doc/scribblings/reference/memory.scrbl b/pkgs/racket-doc/scribblings/reference/memory.scrbl index d67ca8bcf9..1fd3e970b8 100644 --- a/pkgs/racket-doc/scribblings/reference/memory.scrbl +++ b/pkgs/racket-doc/scribblings/reference/memory.scrbl @@ -307,7 +307,7 @@ cause a major collection); minor collections triggered by @racket[collect-garbage] do not cause major collections to run any sooner than they would have otherwise. -@history[#:changed "6.2.900.17" @elem{Added the @racket[request] argument.}]} +@history[#:changed "6.3" @elem{Added the @racket[request] argument.}]} @defproc[(current-memory-use [cust custodian? #f]) exact-nonnegative-integer?]{ diff --git a/pkgs/racket-doc/scribblings/reference/numbers.scrbl b/pkgs/racket-doc/scribblings/reference/numbers.scrbl index ee9771adbe..30647d85da 100644 --- a/pkgs/racket-doc/scribblings/reference/numbers.scrbl +++ b/pkgs/racket-doc/scribblings/reference/numbers.scrbl @@ -945,7 +945,7 @@ the @tt{RtlGenRand} system function. (eval:alts (crypto-random-bytes 14) #"\0\1\1\2\3\5\b\r\25\"7Y\220\351") ] -@history[#:added "6.2.900.17"]} +@history[#:added "6.3"]} @; ------------------------------------------------------------------------ @subsection{Number--String Conversions} diff --git a/pkgs/racket-doc/scribblings/reference/os-lib.scrbl b/pkgs/racket-doc/scribblings/reference/os-lib.scrbl index dfa6827575..15bceb7394 100644 --- a/pkgs/racket-doc/scribblings/reference/os-lib.scrbl +++ b/pkgs/racket-doc/scribblings/reference/os-lib.scrbl @@ -7,7 +7,7 @@ @defmodule[racket/os]{The @racketmodname[racket/os] library additional functions for querying the operating system.} -@history[#:added "6.2.900.17"] +@history[#:added "6.3"] @defproc[(gethostname) string?]{ Returns a string for the current machine's hostname (including its domain). diff --git a/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl b/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl index 5ceeb576f9..4b557d49e1 100644 --- a/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl +++ b/pkgs/racket-doc/scribblings/reference/pretty-print.scrbl @@ -68,7 +68,7 @@ The keyword argument @racket[mode] controls whether printing is done like either @racket[pretty-print] (the default), @racket[pretty-write] or @racket[pretty-display]. -@history[#:changed "6.2.900.15" @elem{Added a @racket[mode] argument.}]} +@history[#:changed "6.3" @elem{Added a @racket[mode] argument.}]} @defproc[(pretty-print-handler [v any/c]) void?]{ diff --git a/pkgs/racket-doc/scribblings/reference/promise.scrbl b/pkgs/racket-doc/scribblings/reference/promise.scrbl index 6764e105c7..beb3a8df91 100644 --- a/pkgs/racket-doc/scribblings/reference/promise.scrbl +++ b/pkgs/racket-doc/scribblings/reference/promise.scrbl @@ -83,7 +83,7 @@ the sense of @racket[promise-running?] and @racket[promise-forced?].} @defproc[(promise/name? [promise any/c]) boolean?]{ Returns @racket[#t] if @racket[promise] is a promise created with @racket[delay/name]. -@history[#:added "6.2.900.5"] +@history[#:added "6.3"] } @defform[(delay/strict body ...+)]{ diff --git a/pkgs/racket-doc/scribblings/reference/sequences.scrbl b/pkgs/racket-doc/scribblings/reference/sequences.scrbl index 7933574c63..d82c0bb81d 100644 --- a/pkgs/racket-doc/scribblings/reference/sequences.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sequences.scrbl @@ -792,7 +792,7 @@ If @racket[min-count] is a number, the stream is required to have at least that (for/list ([x (in-syntax #'(1 2 3))]) x)] -@history[#:added "6.2.900.9"]} +@history[#:added "6.3"]} @defproc[(in-slice [length exact-positive-integer?] [seq sequence?]) sequence?]{ @@ -802,7 +802,7 @@ If @racket[min-count] is a number, the stream is required to have at least that @examples[#:eval sequence-evaluator (for/list ([e (in-slice 3 (in-range 8))]) e) ] - @history[#:added "6.2.900.9"] + @history[#:added "6.3"] } diff --git a/pkgs/racket-doc/scribblings/reference/strings.scrbl b/pkgs/racket-doc/scribblings/reference/strings.scrbl index 8df20e525e..a2abd656be 100644 --- a/pkgs/racket-doc/scribblings/reference/strings.scrbl +++ b/pkgs/racket-doc/scribblings/reference/strings.scrbl @@ -510,7 +510,7 @@ trimmed (which is an alternative to using a @tech{regular expression} @defproc[(non-empty-string? [x any/c]) boolean?]{ Returns @racket[#t] if @racket[x] is a string and is not empty; returns @racket[#f] otherwise. -@history[#:added "6.2.900.15"]{} +@history[#:added "6.3"]{} } @deftogether[( @@ -527,7 +527,7 @@ the second argument, respectively. (string-contains? "Racket" "ack") ] -@history[#:added "6.2.900.17"]{} +@history[#:added "6.3"]{} } diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index 7548b0d335..e44b5aab10 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -528,7 +528,7 @@ most sense when a @tech{rename transformer}'s identifier has the the binding creates a binding alias that effectively routes around the @racket[prop:expansion-contexts] property. -@history[#:added "6.2.900.12"]} +@history[#:added "6.3"]} @defproc[(syntax-local-value [id-stx syntax?] @@ -673,7 +673,7 @@ the @exnraise[exn:fail:contract]. If @racket[stx] form does start with @racket[module] or @racket[module*], or if it starts with @racket[module*] in a top-level context, the @exnraise[exn:fail:contract]. -@history[#:added "6.2.900.10"]} +@history[#:added "6.3"]} @defproc[(syntax-local-lift-module-end-declaration [stx syntax?]) diff --git a/pkgs/racket-doc/syntax/scribblings/contract.scrbl b/pkgs/racket-doc/syntax/scribblings/contract.scrbl index cea469c839..b25b9a9ce1 100644 --- a/pkgs/racket-doc/syntax/scribblings/contract.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/contract.scrbl @@ -68,7 +68,7 @@ The other arguments have the same meaning as for @racket[expr/c]. (app (lambda (x) 'pear) 5) ] -@history[#:added "6.2.900.6"]{} +@history[#:added "6.3"]{} } @close-eval[the-eval] diff --git a/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl b/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl index e1c6f39f4a..3665dcc6d6 100644 --- a/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl @@ -69,7 +69,7 @@ exactly. (lambda () (convert-syntax-error (lambda)))) ] -@history[#:added "6.2.900.6"]{} +@history[#:added "6.3"]{} } @(close-eval the-eval) diff --git a/pkgs/racket-doc/syntax/scribblings/module-reader.scrbl b/pkgs/racket-doc/syntax/scribblings/module-reader.scrbl index aa8d7376fa..90d2a22537 100644 --- a/pkgs/racket-doc/syntax/scribblings/module-reader.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/module-reader.scrbl @@ -364,7 +364,7 @@ For such cases, however, the alternative reader constructor @racket[make-meta-reader] implements a might tightly controlled reading of the module language. -@history[#:changed "6.2.900.6" @elem{Added the @racket[#:module-reader] option.}]} +@history[#:changed "6.3" @elem{Added the @racket[#:module-reader] option.}]} @defproc[(make-meta-reader [self-sym symbol?] From 9fe486b9e053b742248d9cda7ef5ec47a4e201ed Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 12 Oct 2015 14:43:19 -0500 Subject: [PATCH 314/381] Add missing history annotations. Please merge to 6.3. --- .../scribblings/reference/networking.scrbl | 4 ++++ .../scribblings/reference/pairs.scrbl | 19 +++++++++++++++---- .../scribblings/reference/struct.scrbl | 4 ++++ .../syntax/scribblings/macro-testing.scrbl | 4 ++++ .../syntax/scribblings/srcloc.scrbl | 2 ++ .../syntax/scribblings/transformer.scrbl | 1 + 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/networking.scrbl b/pkgs/racket-doc/scribblings/reference/networking.scrbl index 2fb05d19b2..b1d80c43cd 100644 --- a/pkgs/racket-doc/scribblings/reference/networking.scrbl +++ b/pkgs/racket-doc/scribblings/reference/networking.scrbl @@ -257,10 +257,14 @@ port returned by @racket[tcp-accept], @racket[tcp-connect], @defthing[port-number? contract?]{ Equivalent to @racket[(between/c 1 65535)]. + +@history[#:added "6.3"]{} } @defthing[listen-port-number? contract?]{ Equivalent to @racket[(between/c 0 65535)]. + +@history[#:added "6.3"]{} } @;------------------------------------------------------------------------ diff --git a/pkgs/racket-doc/scribblings/reference/pairs.scrbl b/pkgs/racket-doc/scribblings/reference/pairs.scrbl index c91662540e..88b87c44f2 100644 --- a/pkgs/racket-doc/scribblings/reference/pairs.scrbl +++ b/pkgs/racket-doc/scribblings/reference/pairs.scrbl @@ -875,7 +875,9 @@ Returns a list that is the same as @racket[lst] except at the specified index. The element at the specified index is @racket[(updater (list-ref lst pos))]. @examples[#:eval list-eval -(list-update '(zero one two) 1 symbol->string)]} +(list-update '(zero one two) 1 symbol->string)] +@history[#:added "6.3"]{} +} @defproc[(list-set [lst list?] [pos (and/c (>=/c 0) (list [v any/c] @@ -671,6 +673,8 @@ the inaccessible fields are omitted from the list. (struct->list 'not-a-struct #:on-opaque 'return-false) (struct->list 'not-a-struct #:on-opaque 'skip) ] + +@history[#:added "6.3"]{} } @;------------------------------------------------------------------------ diff --git a/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl b/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl index 3665dcc6d6..4630c68ac2 100644 --- a/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/macro-testing.scrbl @@ -33,6 +33,8 @@ converted to a run-time exception. (phase1-eval (extract-struct-info (syntax-local-value #'point)) #:quote quote-syntax) ] + +@history[#:added "6.3"]{} } @defform[(convert-compile-time-error expr)]{ @@ -54,6 +56,8 @@ compile-time error checking like syntax errors: Without the use of @racket[convert-compile-time-error], the checks above would not be executed because the test program would not compile. + +@history[#:added "6.3"]{} } @defform[(convert-syntax-error expr)]{ diff --git a/pkgs/racket-doc/syntax/scribblings/srcloc.scrbl b/pkgs/racket-doc/syntax/scribblings/srcloc.scrbl index ae46c1f68b..97b0c5e229 100644 --- a/pkgs/racket-doc/syntax/scribblings/srcloc.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/srcloc.scrbl @@ -244,6 +244,8 @@ with a path. (syntax-source-directory stx2) (syntax-source-directory stx2) ] + +@history[#:added "6.3"]{} } @subsection{Quoting} diff --git a/pkgs/racket-doc/syntax/scribblings/transformer.scrbl b/pkgs/racket-doc/syntax/scribblings/transformer.scrbl index b673c605aa..9ef434e937 100644 --- a/pkgs/racket-doc/syntax/scribblings/transformer.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/transformer.scrbl @@ -34,6 +34,7 @@ considered immutable and a syntax error is raised. op ] +@history[#:added "6.3"]{} } @close-eval[the-eval] From 511fa20825a09976c24351acbc21add2db912f64 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 12 Oct 2015 14:49:57 -0500 Subject: [PATCH 315/381] Fix flag name. Bring in line with docs. Please merge to 6.3. --- racket/collects/pkg/main.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/pkg/main.rkt b/racket/collects/pkg/main.rkt index a658d357c6..2541da8ea8 100644 --- a/racket/collects/pkg/main.rkt +++ b/racket/collects/pkg/main.rkt @@ -581,7 +581,7 @@ [(#:str state-database #f) state () "Read/write as state of "] [(#:str vers #f) version ("-v") "Copy information suitable for Racket "] [#:bool relative () "Make source paths relative when possible"] - [(#:sym mode [fail ignore continue] 'fail) pkg-fail () + [(#:sym mode [fail skip continue] 'fail) pkg-fail () ("Select handling of package-download failure;" "s: fail (the default), skip, continue (but with exit status of 5)")] #:args (dest-dir . src-catalog) From 42eb8ae332c67a11ba3935e12d2f3296c15cc21f Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 12 Oct 2015 15:40:22 -0500 Subject: [PATCH 316/381] Do shallower checkouts if possible. --- racket/collects/pkg/private/download.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/racket/collects/pkg/private/download.rkt b/racket/collects/pkg/private/download.rkt index 781e1e0d99..f7b4e88a4d 100644 --- a/racket/collects/pkg/private/download.rkt +++ b/racket/collects/pkg/private/download.rkt @@ -111,7 +111,8 @@ (regexp-replace #rx"\n$" s "")) (log-pkg-debug (strip-ending-newline (apply format fmt args)))) #:transport transport - #:strict-links? #t))) + #:strict-links? #t + #:depth 1))) (set! unpacked? #t) ;; package directory as ".tgz" so it can be cached: (parameterize ([current-directory dest-dir]) From 20f31fb74289a8bf38bf22fe8f47ed6ff0a22c0e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 12 Oct 2015 19:25:27 -0600 Subject: [PATCH 317/381] set a bit to prevent corruption of flags via hashing Certain datatypes in the runtime system are not supposed to be hashed, where bits normally reserved for hash codes are used for other purposes. A bad bytecode file can cause some of those to be hashed, anyway. Normally, the damage is isolated to that content of the damaged bytecode, but certain variable-reference bytecode forms are both shared and non-hashable. Set a bit that ensures hashing will not change flags in the shared object. This problem was exposed by fuzz testing. --- racket/src/racket/src/compenv.c | 8 ++++---- racket/src/racket/src/schpriv.h | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index f2676bd996..4dc3a8f05a 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -630,7 +630,7 @@ Scheme_Object *scheme_make_toplevel(mzshort depth, int position, int resolved, i tl->iso.so.type = (resolved ? scheme_toplevel_type : scheme_compiled_toplevel_type); tl->depth = depth; tl->position = position; - SCHEME_TOPLEVEL_FLAGS(tl) = flags; + SCHEME_TOPLEVEL_FLAGS(tl) = flags | HIGH_BIT_TO_DISABLE_HASHING; if (resolved) { if (toplevels_ht->count > TABLE_CACHE_MAX_SIZE) { @@ -801,7 +801,7 @@ static void init_scheme_local() #endif v->type = k + scheme_local_type; SCHEME_LOCAL_POS(v) = i; - SCHEME_LOCAL_FLAGS(v) = cor; + SCHEME_LOCAL_FLAGS(v) = cor | HIGH_BIT_TO_DISABLE_HASHING; scheme_local[i][k][cor] = v; } @@ -841,7 +841,7 @@ static void init_toplevels() v->iso.so.type = scheme_toplevel_type; v->depth = i; v->position = k; - SCHEME_TOPLEVEL_FLAGS(v) = cnst; + SCHEME_TOPLEVEL_FLAGS(v) = cnst | HIGH_BIT_TO_DISABLE_HASHING; toplevels[i][k][cnst] = (Scheme_Object *)v; } @@ -888,7 +888,7 @@ Scheme_Object *scheme_make_local(Scheme_Type type, int pos, int flags) return v; v = alloc_local(type, pos); - SCHEME_LOCAL_FLAGS(v) = flags; + SCHEME_LOCAL_FLAGS(v) = flags | HIGH_BIT_TO_DISABLE_HASHING; if (locals_ht[k]->count > TABLE_CACHE_MAX_SIZE) { Scheme_Hash_Table *ht; diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 0a25dc45b4..b575ee1979 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -1495,6 +1495,8 @@ typedef struct { Scheme_Object *body; } Scheme_With_Continuation_Mark; +#define HIGH_BIT_TO_DISABLE_HASHING 0x2000 + typedef struct Scheme_Local { Scheme_Inclhash_Object iso; /* keyex used for flags and type info (and can't be hashed) */ mzshort position; @@ -1513,8 +1515,8 @@ typedef struct Scheme_Local { #define SCHEME_LOCAL_OTHER_CLEARS 2 #define SCHEME_LOCAL_TYPE_OFFSET 2 -#define SCHEME_GET_LOCAL_FLAGS(obj) SCHEME_LOCAL_FLAGS(obj) -#define SCHEME_GET_LOCAL_TYPE(obj) ((SCHEME_LOCAL_FLAGS(obj) > 2) ? (SCHEME_LOCAL_FLAGS(obj) - 2) : 0) +#define SCHEME_GET_LOCAL_FLAGS(obj) (SCHEME_LOCAL_FLAGS(obj) & ~HIGH_BIT_TO_DISABLE_HASHING) +#define SCHEME_GET_LOCAL_TYPE(obj) ((SCHEME_GET_LOCAL_FLAGS(obj) > 2) ? (SCHEME_GET_LOCAL_FLAGS(obj) - 2) : 0) typedef struct Scheme_Toplevel { Scheme_Inclhash_Object iso; /* keyex used for flags (and can't be hashed) */ From e53492a68f5bdea335feb238bcc6e06993e900d3 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sun, 11 Oct 2015 10:55:36 -0400 Subject: [PATCH 318/381] Support environment variable for setting global seed. --- pkgs/racket-test/tests/racket/stress/fuzz.rkt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/racket/stress/fuzz.rkt b/pkgs/racket-test/tests/racket/stress/fuzz.rkt index fc7c706939..e9b42ee488 100644 --- a/pkgs/racket-test/tests/racket/stress/fuzz.rkt +++ b/pkgs/racket-test/tests/racket/stress/fuzz.rkt @@ -51,8 +51,9 @@ (error "--write requires -f")) (set! write? filename))] #:args () (void)) - (unless global-seed - (set! global-seed (+ 1 (random (expt 2 30))))) + (cond [global-seed] + [(getenv "RACKET_FUZZ_GLOBAL_SEED") => (lambda (v) (set! global-seed (string->number v)))] + [else (set! global-seed (+ 1 (random (expt 2 30))))]) (printf "Global seed: ~a\n" global-seed) (random-seed global-seed) (let loop () From f63188b4ea6e063f9eb30084de13763c627c25a1 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sun, 11 Oct 2015 14:03:24 -0400 Subject: [PATCH 319/381] Refactoring. --- pkgs/racket-test/tests/racket/stress/fuzz.rkt | 94 ++++++++++++------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/pkgs/racket-test/tests/racket/stress/fuzz.rkt b/pkgs/racket-test/tests/racket/stress/fuzz.rkt index e9b42ee488..897060b352 100644 --- a/pkgs/racket-test/tests/racket/stress/fuzz.rkt +++ b/pkgs/racket-test/tests/racket/stress/fuzz.rkt @@ -7,7 +7,7 @@ (define val (bytes-ref bs byte)) (bytes-set! bs byte (bitwise-xor (expt 2 bit) val))) -(define (run-file bs) +(define (run-bytes bs) (sync (parameterize ([current-custodian (make-custodian)]) (thread @@ -18,7 +18,7 @@ (eval (parameterize ([read-accept-compiled #t]) (with-input-from-bytes bs read))))))))) -(define (run fname seed0 #:write? [out-fname? #f]) +(define (run-file fname seed0 #:write? [out-fname? #f]) (define seed (or seed0 (+ 1 (random (expt 2 30))))) (printf "seed: ~s\nname: ~a\n" seed fname) (flush-output) @@ -33,44 +33,72 @@ (call-with-output-file (build-path (current-directory) out-fname?) (lambda (o) (write-bytes bs o)))) - (run-file bs)))) + (run-bytes bs)))) -(let ([seed0 #f] [file #f] [dir #f] [forever? #f] [global-seed #f] [write? #f]) - (command-line - #:once-each - ["--oo" "forever" (set! forever? #t)] - #:once-any - ["-g" global-seed* "gloabl random seed" (set! global-seed (string->number global-seed*))] - ["-s" seed "random seed" (set! seed0 (string->number seed))] - #:once-any - ["-f" file* "filename to run" (set! file file*)] - ["-d" dir* "dir to run" (set! dir dir*)] - ["-c" "run over all collections" (set! dir (find-collects-dir))] - #:once-any - ["--write" filename "write mutated file" (begin (unless file - (error "--write requires -f")) - (set! write? filename))] - #:args () (void)) - (cond [global-seed] - [(getenv "RACKET_FUZZ_GLOBAL_SEED") => (lambda (v) (set! global-seed (string->number v)))] - [else (set! global-seed (+ 1 (random (expt 2 30))))]) +(define (go) + (let ([seed0 #f] [file #f] [dir #f] [forever? #f] [global-seed #f] [write? #f]) + (printf ">>> ~s\n" (current-command-line-arguments)) + (command-line + #:once-each + ["--oo" "forever" (set! forever? #t)] + #:once-any + ["-g" global-seed* "global random seed" (set! global-seed (string->number global-seed*))] + ["-s" seed "random seed" (set! seed0 (string->number seed))] + #:once-any + ["-f" file* "filename to run" (set! file file*)] + ["-d" dir* "dir to run" (set! dir dir*)] + ["-c" "run over all collections" (set! dir (find-collects-dir))] + #:once-any + ["--write" filename "write mutated file" (begin (unless file + (error "--write requires -f")) + (set! write? filename))] + #:args () (void)) + (cond [global-seed] + [(getenv "RACKET_FUZZ_GLOBAL_SEED") => (lambda (v) (set! global-seed (string->number v)))] + [else (set! global-seed (+ 1 (random (expt 2 30))))]) + (run seed0 file dir forever? global-seed write?))) + +(define (run seed0 file dir forever? global-seed write?) (printf "Global seed: ~a\n" global-seed) (random-seed global-seed) (let loop () - (cond [file (run file seed0 #:write? write?)] + (cond [file (run-file file seed0 #:write? write?)] [dir - (define files (sort (for/list ([f (in-directory dir)] - #:when (regexp-match #rx"\\.zo" f)) - f) - #:key path->string - stringstring + string>> ~s\n" (current-command-line-arguments)) + (command-line + #:once-each + ["--oo" "forever" (set! forever? #t)] + #:once-any + ["-g" global-seed* "global random seed" (set! global-seed (string->number global-seed*))] + ["-s" seed "random seed" (set! seed0 (string->number seed))] + #:once-any + ["-f" file* "filename to run" (set! file file*)] + ["-d" dir* "dir to run" (set! dir dir*)] + ["-c" "run over all collections" (set! dir (find-collects-dir))] + #:once-any + ["--write" filename "write mutated file" (begin (unless file + (error "--write requires -f")) + (set! write? filename))] + #:args () (void)) + (cond [global-seed] + [(getenv "RACKET_FUZZ_GLOBAL_SEED") => (lambda (v) (set! global-seed (string->number v)))] + [else (set! global-seed (+ 1 (random (expt 2 30))))]) + (run seed0 file dir forever? global-seed write?))) + +(module+ test + (require racket/vector syntax/location) + (parameterize ([current-command-line-arguments (vector-append #("-c") (current-command-line-arguments))]) + (dynamic-require (quote-module-path ".." main) #f)) (module config info (define random? #t))) From f400dab91253f7a5e619b7f29dfad067371fc186 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 13 Oct 2015 17:48:03 -0400 Subject: [PATCH 320/381] Add a check in the compilation-top reader. This bug was found by fuzz testing. --- racket/src/racket/src/marshal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 66a9e0750b..44e7b7573d 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -338,6 +338,7 @@ static Scheme_Object *read_top(Scheme_Object *obj) top->iso.so.type = scheme_compilation_top_type; if (!SCHEME_PAIRP(obj)) return NULL; top->max_let_depth = SCHEME_INT_VAL(SCHEME_CAR(obj)); + if (top->max_let_depth < 0) return NULL; /* Should this check for a max as well? */ obj = SCHEME_CDR(obj); if (!SCHEME_PAIRP(obj)) return NULL; top->binding_namess = SCHEME_CAR(obj); /* checking is in scheme_install_binding_names() */ From a3142ac2575c8591c8fd14940e099f3e7befc9a9 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 14 Oct 2015 09:38:56 -0400 Subject: [PATCH 321/381] Increase sleep time to avoid races on loaded test machines. Hopefully alleviates DrDr & Travis failures. --- pkgs/racket-test/tests/pkg/tests-locking.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test/tests/pkg/tests-locking.rkt b/pkgs/racket-test/tests/pkg/tests-locking.rkt index 6cf7378ea2..767c70f8e3 100644 --- a/pkgs/racket-test/tests/pkg/tests-locking.rkt +++ b/pkgs/racket-test/tests/pkg/tests-locking.rkt @@ -26,7 +26,7 @@ #:command-line? #t #:servlet-regexp #rx"" #:port 9967) - (sleep 1))) + (sleep 2))) ;; Step 2: Assign it as our server $ "raco pkg config --set catalogs http://localhost:9967" @@ -36,7 +36,7 @@ (λ () (shelly-begin $ "raco pkg install pkg-test1"))) - (sleep 1) + (sleep 2) ;; Step 4: Start the installation request that will fail $ "raco pkg install pkg-test1" =exit> 1 From 297fb750092fe8dece2bdcfa26fa4078d2139968 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 14 Oct 2015 09:39:38 -0400 Subject: [PATCH 322/381] Support `-q` flag for individual pkg tests. --- pkgs/racket-test/tests/pkg/util.rkt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/pkg/util.rkt b/pkgs/racket-test/tests/pkg/util.rkt index 944b274b32..918b6cb754 100644 --- a/pkgs/racket-test/tests/pkg/util.rkt +++ b/pkgs/racket-test/tests/pkg/util.rkt @@ -168,7 +168,14 @@ e ...)) (provide run-pkg-tests) (module+ main - (run-pkg-tests* run-pkg-tests)))))])) + (require racket/cmdline) + (define verb? #t) + (command-line + #:once-each + ["-q" "run quietly" (set! verb? #f)] + #:args () (void)) + (parameterize ([verbose? verb?]) + (run-pkg-tests* run-pkg-tests))))))])) (define (run-pkg-tests* t) (putenv "PLT_PKG_NOSETUP" "y") From a4d292b21a70452c4f04d24211c03c2eba1f49ac Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 14 Oct 2015 15:27:13 -0400 Subject: [PATCH 323/381] Use an unsigned type for sizes. Fixes this crash http://drdr.racket-lang.org/32121/pkgs/racket-test/tests/racket/stress/fuzz.rkt found by fuzz testing. --- racket/src/racket/src/read.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 0e108604bc..f9126e2fca 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -5447,7 +5447,7 @@ Scheme_Object *scheme_string_to_submodule_path(char *_s, intptr_t len) { unsigned char *s = (unsigned char *)_s; char *e, buffer[32]; - intptr_t pos = 0, l; + uintptr_t pos = 0, l; Scheme_Object *first = NULL, *last = NULL, *pr; while (pos < len) { From 03bf7d3def7048f41353aa12d5e7eb90c429eff0 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 14 Oct 2015 15:28:19 -0400 Subject: [PATCH 324/381] Remove added printf. --- pkgs/racket-test/tests/racket/stress/fuzz.rkt | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/racket-test/tests/racket/stress/fuzz.rkt b/pkgs/racket-test/tests/racket/stress/fuzz.rkt index 897060b352..aea6cff8dd 100644 --- a/pkgs/racket-test/tests/racket/stress/fuzz.rkt +++ b/pkgs/racket-test/tests/racket/stress/fuzz.rkt @@ -37,7 +37,6 @@ (define (go) (let ([seed0 #f] [file #f] [dir #f] [forever? #f] [global-seed #f] [write? #f]) - (printf ">>> ~s\n" (current-command-line-arguments)) (command-line #:once-each ["--oo" "forever" (set! forever? #t)] @@ -75,7 +74,6 @@ (module+ main (let ([seed0 #f] [file #f] [dir #f] [forever? #f] [global-seed #f] [write? #f]) - (printf ">>> ~s\n" (current-command-line-arguments)) (command-line #:once-each ["--oo" "forever" (set! forever? #t)] From 6199f9a5967386c76317bcef0c20c1d8160de32b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 15 Oct 2015 15:57:44 -0600 Subject: [PATCH 325/381] GC: use generation 1/2 consistently within a collection The rule for using generation 1/2is based on the current memory use versus the maximum size of generation 0. Recent changes to the GC have caused that size to vary during a collection, which means that the choice to use generation 1/2 or not can change within a collection. Partial use of generation 1/2 doesn't inherently cause problems, but it can cause a generation-1 object to point to a generation-1/2 object even though the former was allocated after the latter. That's a problem on if getting generations out of order relative to allocation order can create problems. As it happens, reset_finalizer_tree() checks the generation of the finalization record and not the finalized pointer, because the record is always allocated after the pointer. Merge to v6.3 --- racket/src/racket/gc2/newgc.c | 4 +++- racket/src/racket/gc2/newgc.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 40748c32bc..ff7efcbec8 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -3580,7 +3580,7 @@ void GC_mark2(void *pp, struct NewGC *gc) size = gcWORDS_TO_BYTES(ohead->size); - if (AGE_GEN_0_TO_GEN_HALF(gc) && (page->generation == AGE_GEN_0) && !gc->gc_full) { + if (gc->use_gen_half && (page->generation == AGE_GEN_0)) { /* move to generation 1/2 */ work = gc->gen_half.curr_alloc_page; if (!work || (work->size + size > GEN0_PAGE_SIZE)) { @@ -5023,6 +5023,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->in_unsafe_allocation_mode = 1; gc->unsafe_allocation_abort = out_of_memory_gc; + gc->use_gen_half = !gc->gc_full && AGE_GEN_0_TO_GEN_HALF(gc); + if (gc->gc_full) gc->phantom_count = 0; else if (gc->memory_in_use > gc->phantom_count) { diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 0e86dbc228..a979c75c2a 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -193,6 +193,7 @@ typedef struct NewGC { unsigned char full_needed_for_finalization :1; unsigned char no_further_modifications :1; unsigned char gc_full :1; /* a flag saying if this is a full/major collection */ + unsigned char use_gen_half :1; unsigned char running_finalizers :1; unsigned char back_pointers :1; unsigned char need_fixup :1; From d47b96970c79b28980cede2a74d59d8e6e61c846 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 29 Sep 2015 21:02:31 -0400 Subject: [PATCH 326/381] make Windows build work on case-sensitive filesystems --- racket/collects/launcher/launcher.rkt | 2 +- racket/src/racket/cmdline.inc | 2 +- racket/src/racket/src/fun.c | 4 ++-- racket/src/worksp/mrstart/mrstart.vcxproj | 4 ++-- racket/src/worksp/mzstart/mzstart.vcxproj | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/racket/collects/launcher/launcher.rkt b/racket/collects/launcher/launcher.rkt index eb0b9fcda9..162fc5b939 100644 --- a/racket/collects/launcher/launcher.rkt +++ b/racket/collects/launcher/launcher.rkt @@ -602,7 +602,7 @@ (find-collects-dir))) ;; Independent launcher (needed for Setup PLT): (begin - (install-template dest kind "mzstart.exe" "mrstart.exe") + (install-template dest kind "MzStart.exe" "MrStart.exe") (let ([bstr (bytes->utf-16-bytes (string->bytes/utf-8 (str-list->dos-str (list* "-N" diff --git a/racket/src/racket/cmdline.inc b/racket/src/racket/cmdline.inc index e7163fc619..0d56b56019 100644 --- a/racket/src/racket/cmdline.inc +++ b/racket/src/racket/cmdline.inc @@ -94,7 +94,7 @@ static int _configdir_offset = 17; /* Skip permanent tag */ #endif #ifdef DOS_FILE_SYSTEM -# include +# include #ifndef DLL_RELATIVE_PATH # define DLL_RELATIVE_PATH L"lib" diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index c1414f34a5..540d03fb97 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -36,7 +36,7 @@ /* The implementations of the time primitives, such as `current-seconds', vary a lot from platform to platform. */ #ifdef USE_WIN32_TIME -# include +# include #else # if defined(OSKIT) && !defined(OSKIT_TEST) /* Get FreeBSD version, not oskit/time.h version */ @@ -56,7 +56,7 @@ # define USE_GETRUSAGE # endif /* USE_SYSCALL_GETRUSAGE */ # ifdef WINDOWS_GET_PROCESS_TIMES -# include +# include # endif # if !defined(USE_GETRUSAGE) && !defined(WINDOWS_GET_PROCESS_TIMES) && !defined(USER_TIME_IS_CLOCK) # include diff --git a/racket/src/worksp/mrstart/mrstart.vcxproj b/racket/src/worksp/mrstart/mrstart.vcxproj index 3daf265623..42b731c762 100644 --- a/racket/src/worksp/mrstart/mrstart.vcxproj +++ b/racket/src/worksp/mrstart/mrstart.vcxproj @@ -71,7 +71,7 @@ /MACHINE:I386 %(AdditionalOptions) user32.lib;%(AdditionalDependencies) - ..\..\..\lib\mrstart.exe + ..\..\..\lib\MrStart.exe true true ..\..\..\lib\mrstart.pdb @@ -108,7 +108,7 @@ user32.lib;%(AdditionalDependencies) - ..\..\..\lib\mrstart.exe + ..\..\..\lib\MrStart.exe true true ..\..\..\lib\mrstart.pdb diff --git a/racket/src/worksp/mzstart/mzstart.vcxproj b/racket/src/worksp/mzstart/mzstart.vcxproj index 57e009aec9..c74d930597 100644 --- a/racket/src/worksp/mzstart/mzstart.vcxproj +++ b/racket/src/worksp/mzstart/mzstart.vcxproj @@ -63,7 +63,7 @@ /MACHINE:I386 %(AdditionalOptions) - ..\..\..\lib\mzstart.exe + ..\..\..\lib\MzStart.exe true true ..\..\..\lib\mzstart.pdb @@ -92,7 +92,7 @@ ..\starters - ..\..\..\lib\mzstart.exe + ..\..\..\lib\MzStart.exe true true ..\..\..\lib\mzstart.pdb From 4d703fa2e2be0b9a0aa6788696b66afdded4ff24 Mon Sep 17 00:00:00 2001 From: Alex Knauth Date: Mon, 21 Sep 2015 20:46:29 -0400 Subject: [PATCH 327/381] syntax/parse: allow pattern expanders that don't start with tilde --- racket/collects/syntax/parse/private/rep.rkt | 2 -- 1 file changed, 2 deletions(-) diff --git a/racket/collects/syntax/parse/private/rep.rkt b/racket/collects/syntax/parse/private/rep.rkt index 35d9277b5b..10e2e4cfaf 100644 --- a/racket/collects/syntax/parse/private/rep.rkt +++ b/racket/collects/syntax/parse/private/rep.rkt @@ -469,7 +469,6 @@ [id (and (identifier? #'id) (not-shadowed? #'id) - (not (safe-name? #'id)) (pattern-expander? (syntax-local-value #'id (λ () #f)))) (let* ([proc (pattern-expander-proc (syntax-local-value #'id))] [introducer (make-syntax-introducer)] @@ -482,7 +481,6 @@ [(id . rst) (and (identifier? #'id) (not-shadowed? #'id) - (not (safe-name? #'id)) (pattern-expander? (syntax-local-value #'id (λ () #f)))) (let* ([proc (pattern-expander-proc (syntax-local-value #'id))] [introducer (make-syntax-introducer)] From 2acb10a5da1d3b687f665fb12d6e9076f6d0a9d1 Mon Sep 17 00:00:00 2001 From: AlexKnauth Date: Tue, 13 Oct 2015 15:26:13 -0400 Subject: [PATCH 328/381] syntax/parse: add test for non-tilde pattern expander --- pkgs/racket-test/tests/stxparse/test.rkt | 61 +++++++++++++++++------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/pkgs/racket-test/tests/stxparse/test.rkt b/pkgs/racket-test/tests/stxparse/test.rkt index d2e94dffcc..181d002245 100644 --- a/pkgs/racket-test/tests/stxparse/test.rkt +++ b/pkgs/racket-test/tests/stxparse/test.rkt @@ -562,23 +562,23 @@ ;; from http://lists.racket-lang.org/users/archive/2014-June/063095.html (test-case "pattern-expanders" (let () - (define-splicing-syntax-class binding #:literals (=) - [pattern (~seq name:id = expr:expr)]) - - (define-syntax ~separated - (pattern-expander - (lambda (stx) - (syntax-case stx () - [(separated sep pat) - (with-syntax ([ooo '...]) - #'((~seq pat (~or (~peek-not _) - (~seq sep (~peek _)))) - ooo))])))) - - (define-splicing-syntax-class bindings - [pattern (~separated (~datum /) b:binding) - #:with (name ...) #'(b.name ...) - #:with (expr ...) #'(b.expr ...)]) + (define-splicing-syntax-class binding #:literals (=) + [pattern (~seq name:id = expr:expr)]) + + (define-syntax ~separated + (pattern-expander + (lambda (stx) + (syntax-case stx () + [(separated sep pat) + (with-syntax ([ooo '...]) + #'((~seq pat (~or (~peek-not _) + (~seq sep (~peek _)))) + ooo))])))) + + (define-splicing-syntax-class bindings + [pattern (~separated (~datum /) b:binding) + #:with (name ...) #'(b.name ...) + #:with (expr ...) #'(b.expr ...)]) (define (parse-my-let stx) (syntax-parse stx @@ -591,6 +591,33 @@ (+ x y z)))) (syntax->datum #'(let ([x 1] [y 2] [z 3]) (+ x y z)))) + + (define-syntax sep-comma ; test pattern expanders that don't begin with tilde + (pattern-expander + (lambda (stx) + (syntax-case stx () + [(sep-comma pat) + (with-syntax ([ooo '...]) + #'((~seq (~or (~and pat (~not ((~datum unquote) _))) ((~datum unquote) pat)) + (~or (~peek-not _) (~peek ((~datum unquote) _)))) + ooo))])))) + + (define-splicing-syntax-class bindings2 + [pattern (sep-comma [b:binding]) + #:with (name ...) #'(b.name ...) + #:with (expr ...) #'(b.expr ...)]) + + (define (parse-my-let2 stx) + (syntax-parse stx + [(_ bs:bindings2 body) + #'(let ([bs.name bs.expr] ...) + body)])) + + (check-equal? (syntax->datum + (parse-my-let2 #'(my-let ([x = 1], [y = 2], [z = 3]) + (+ x y z)))) + (syntax->datum #'(let ([x 1] [y 2] [z 3]) + (+ x y z)))) )) (test-case "this-syntax" From 6b93b18a1a5d9eceb521401b94a5c91af77f93ef Mon Sep 17 00:00:00 2001 From: Alex Knauth Date: Mon, 21 Sep 2015 20:56:28 -0400 Subject: [PATCH 329/381] syntax/parse: update pattern expander docs --- pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl index d1fd1b5904..a01b5cbbb9 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/patterns.scrbl @@ -1059,9 +1059,8 @@ The grammar of @tech{syntax patterns} is extensible through the use of @deftech{pattern expanders}, which allow the definition of new pattern forms by rewriting them into existing pattern forms. -@margin-note{A @tech{pattern expander}'s name must begin with a @code{~} - character. Otherwise, @racket[syntax-parse] and other - @racketmodname[syntax/parse] forms will not recognize it.} +@margin-note{As a convention to avoid ambiguity, @tech{pattern expander} + names normally begin with a @code{~} character.} @defproc[(pattern-expander [proc (-> syntax? syntax?)]) pattern-expander?]{ From 7db0c3b1d4698d890493ba0f5de56232e6139aed Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 13 Oct 2015 12:44:20 -0600 Subject: [PATCH 330/381] avoid changing mark bits for old objects For a minor GC and pages that contain backpointers, leave mark bits as they are; instead make a pass to shift mark bits for new objects to "dead" bits, and use dead bits for fixup. This change is intended as a small step toward incremental collection. --- racket/src/racket/gc2/newgc.c | 259 +++++++++++++++++++--------------- racket/src/racket/gc2/newgc.h | 4 +- 2 files changed, 145 insertions(+), 118 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index ff7efcbec8..0e21459459 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -4211,7 +4211,6 @@ static void mark_backpointers(NewGC *gc) if (work->size_class == SIZE_CLASS_BIG_PAGE) { /* must be a big page */ - work->size_class = SIZE_CLASS_BIG_PAGE_MARKED; push_ptr(gc, TAG_AS_BIG_PAGE_PTR(BIG_PAGE_TO_OBJECT(work))); gc->memory_in_use -= work->size; } else if (work->size_class == SIZE_CLASS_SMALL_PAGE) { @@ -4223,13 +4222,10 @@ static void mark_backpointers(NewGC *gc) while (start < end) { objhead *info = (objhead *)start; - if (!info->dead) { - info->mark = 1; + if (!info->dead) push_ptr(gc, OBJHEAD_TO_OBJPTR(start)); - } start += info->size; } - work->scan_boundary = PREFIX_SIZE; gc->memory_in_use -= work->size; } else { /* medium page */ @@ -4240,10 +4236,8 @@ static void mark_backpointers(NewGC *gc) while (start <= end) { objhead *info = (objhead *)start; - if (!info->dead) { - info->mark = 1; + if (!info->dead) push_ptr(gc, OBJHEAD_TO_OBJPTR(info)); - } start += info->size; } @@ -4407,58 +4401,6 @@ inline static void do_heap_compact(NewGC *gc) } } -static int repair_mixed_page(NewGC *gc, mpage *page, void **end, int need_fixup) -{ - void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); - Fixup2_Proc *fixup_table = gc->fixup_table; - int non_dead = 0; - - while (start <= end) { - objhead *info = (objhead *)start; - if (info->mark) { - if (need_fixup) { - switch(info->type) { - case PAGE_ARRAY: - { - void **tempend = PPTR(info) + info->size, **tmpstart; - tmpstart = OBJHEAD_TO_OBJPTR(start); - while (tmpstart < tempend) gcFIXUP2(*tmpstart++, gc); - } - break; - case PAGE_TAGGED: - { - void *obj_start = OBJHEAD_TO_OBJPTR(start); - unsigned short tag = *(unsigned short *)obj_start; - ASSERT_TAG(tag); - fixup_table[tag](obj_start, gc); - } - break; - case PAGE_ATOMIC: - break; - case PAGE_PAIR: - { - Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); - } - break; - default: - printf("Unhandled info->type %i\n", info->type); - abort(); - } - } - start += info->size; - info->mark = 0; - non_dead++; - } else { - info->dead = 1; - start += info->size; - } - } - - return non_dead; -} - static void chain_marked_on(NewGC *gc) /* add any page that is marked on to the `modified_next` chain; this is needed for a master GC, because the place GCs do not register @@ -4536,7 +4478,111 @@ static void chain_marked_on_check(NewGC *gc) static void chain_marked_on_check(NewGC *gc) { } #endif +static void unmark_range(void **start, void **end) +{ + while(start < end) { + objhead *info = (objhead *)start; + + if (info->mark) + info->mark = 0; + else + info->dead = 1; + + start += info->size; + } +} + +static void unmark_heap(NewGC *gc) +/* Set `dead` bit if not `mark`, otherwise clean `mark`. After this + pass, objects are live if `dead` is not set. */ +{ + mpage *page; + + /* See start of repair_heap() for more information on the current + page state. */ + + for (page = gc->modified_next; page; page = page->modified_next) { + GC_ASSERT(page->marked_on || page->marked_from); + if (page->generation == AGE_VACATED) { + /* this page will be released later */ + } else { + if (page->size_class >= SIZE_CLASS_BIG_PAGE) { + page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark, if any */ + } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { + GCDEBUG((DEBUGOUTF, "Unmarking objs on page %p, starting with %p\n", + page, start)); + unmark_range(PPTR(NUM(page->addr) + page->scan_boundary), + PAGE_END_VSS(page)); + + /* repair phase should walk the full page: */ + page->scan_boundary = PREFIX_SIZE; + } else { + GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); + if ((page->generation == AGE_GEN_0) || gc->gc_full) + unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), + PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); + } + } + } + + /* All gen-half pages count as modified: */ + for (page = gc->gen_half.pages; page; page = page->next) { + GC_ASSERT(page->generation == AGE_GEN_HALF); + unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), + PPTR(NUM(page->addr) + page->size - 1)); + } +} + +static int repair_mixed_page(NewGC *gc, mpage *page, void **end, int need_fixup) +{ + void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); + Fixup2_Proc *fixup_table = gc->fixup_table; + int non_dead = 0; + + while (start <= end) { + objhead *info = (objhead *)start; + if (!info->dead) { + non_dead++; + if (need_fixup) { + switch(info->type) { + case PAGE_ARRAY: + { + void **tempend = PPTR(info) + info->size, **tmpstart; + tmpstart = OBJHEAD_TO_OBJPTR(start); + while (tmpstart < tempend) gcFIXUP2(*tmpstart++, gc); + } + break; + case PAGE_TAGGED: + { + void *obj_start = OBJHEAD_TO_OBJPTR(start); + unsigned short tag = *(unsigned short *)obj_start; + ASSERT_TAG(tag); + fixup_table[tag](obj_start, gc); + } + break; + case PAGE_ATOMIC: + break; + case PAGE_PAIR: + { + Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + } + break; + default: + printf("Unhandled info->type %i\n", info->type); + abort(); + } + } + } + start += info->size; + } + + return non_dead; +} + static void repair_heap(NewGC *gc) +/* not dead => fixup pointers */ { uintptr_t memory_in_use; mpage *page, *next; @@ -4577,7 +4623,6 @@ static void repair_heap(NewGC *gc) GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", page, start)); - page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark */ if (need_fixup) { switch(page->page_type) { case PAGE_TAGGED: @@ -4599,71 +4644,52 @@ static void repair_heap(NewGC *gc) memory_in_use += page->size; } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { - void **start = PPTR(NUM(page->addr) + page->scan_boundary); - void **end = PAGE_END_VSS(page); + if (need_fixup) { + void **start = PPTR(NUM(page->addr) + page->scan_boundary); + void **end = PAGE_END_VSS(page); + GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", + page, start)); + switch(page->page_type) { + case PAGE_TAGGED: + while(start < end) { + objhead *info = (objhead *)start; - GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", - page, start)); - switch(page->page_type) { - case PAGE_TAGGED: - while(start < end) { - objhead *info = (objhead *)start; - - if(info->mark) { - void *obj_start = OBJHEAD_TO_OBJPTR(start); - unsigned short tag = *(unsigned short *)obj_start; - ASSERT_TAG(tag); - info->mark = 0; - if (need_fixup) + if(!info->dead) { + void *obj_start = OBJHEAD_TO_OBJPTR(start); + unsigned short tag = *(unsigned short *)obj_start; + ASSERT_TAG(tag); fixup_table[tag](obj_start, gc); - } else - info->dead = 1; - start += info->size; - } - break; - case PAGE_ATOMIC: - while(start < end) { - objhead *info = (objhead *)start; - if(info->mark) - info->mark = 0; - else - info->dead = 1; - start += info->size; - } - break; - case PAGE_ARRAY: - while(start < end) { - objhead *info = (objhead *)start; - size_t size = info->size; - if(info->mark) { - void **tempend = PPTR(info) + info->size; - if (need_fixup) { + } + start += info->size; + } + break; + case PAGE_ATOMIC: + break; + case PAGE_ARRAY: + while(start < end) { + objhead *info = (objhead *)start; + size_t size = info->size; + if(!info->dead) { + void **tempend = PPTR(info) + info->size; start = OBJHEAD_TO_OBJPTR(start); while(start < tempend) gcFIXUP2(*start++, gc); - } else - start = tempend; - info->mark = 0; - } else { - info->dead = 1; - start += size; + } else { + start += size; + } } - } - break; - case PAGE_PAIR: - while(start < end) { - objhead *info = (objhead *)start; - if(info->mark) { - if (need_fixup) { + break; + case PAGE_PAIR: + while(start < end) { + objhead *info = (objhead *)start; + if(!info->dead) { Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); gcFIXUP2(SCHEME_CAR(p), gc); gcFIXUP2(SCHEME_CDR(p), gc); } - info->mark = 0; - } else - info->dead = 1; - start += PAIR_SIZE_IN_BYTES >> LOG_WORD_SIZE; + start += PAIR_SIZE_IN_BYTES >> LOG_WORD_SIZE; + } + break; } - break; } page->scan_boundary = page->size; @@ -5149,6 +5175,7 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin chain_marked_on(gc); else if (gc->gc_full) chain_marked_on_check(gc); + unmark_heap(gc); repair_heap(gc); TIME_STEP("repaired"); clean_up_heap(gc); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index a979c75c2a..a730aef9c9 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -35,8 +35,8 @@ typedef struct mpage { uintptr_t alloc_size; /* for a nursery: total size of the nursery */ uintptr_t med_search_start; /* medium page: offset for searching for a free slot */ uintptr_t scan_boundary; /* small gen1 page: during GC, boundary between objects that can be - left alone and that that will be scanned & fixed up; objects before - have cleared "mark" bits, while objects after (may) have "mark" bits sets */ + should be treated as previously gen1 and objects that should be + treated as just moved from gen0 */ }; unsigned short live_size; /* except for big pages, total size of live objects on the page */ unsigned char generation :2; From c50c23c134b73d48dd63e65aed390090f5b721ad Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 13 Oct 2015 16:40:23 -0600 Subject: [PATCH 331/381] GC: toward incremental collection Make the old-generation marking process incremental on request, where `(collect-garbage 'incremental)` makes a request. Only the marking phase of an old-generation collection is incremental, so far. In exchange for slower minor collections and a larger heap, you get a major collection pause time that is roughly halved. So, this is a step forward, but not good enough for most purposes that need incremental collection. An incremental-mode request sticks until the next major GC. The idea is that any program that could benefit from incremental collection will have some sort of periodic task where it can naturally request incremental mode. (In particular, that request belongs in the program, not in some external flag to the runtime system.) Otherwise, the system should revert to non-incremental mode, given that incremental mode is slower overall and can use much more memory --- usually within a factor of two, but the factor can be much worse due to fragmentation. --- pkgs/base/info.rkt | 2 +- .../scribblings/reference/memory.scrbl | 52 +- racket/src/racket/gc2/README | 11 + racket/src/racket/gc2/commongc_internal.h | 3 + racket/src/racket/gc2/fnls.c | 13 +- racket/src/racket/gc2/gc2.h | 30 +- racket/src/racket/gc2/mem_account.c | 18 +- racket/src/racket/gc2/newgc.c | 1157 ++++++++++++----- racket/src/racket/gc2/newgc.h | 47 +- racket/src/racket/gc2/weak.c | 284 +++- racket/src/racket/include/schthread.h | 2 + racket/src/racket/src/eval.c | 33 +- racket/src/racket/src/mzclpf_decl.inc | 1 + racket/src/racket/src/mzclpf_post.inc | 31 +- racket/src/racket/src/mzclpf_pre.inc | 16 +- racket/src/racket/src/schpriv.h | 4 +- racket/src/racket/src/schvers.h | 4 +- racket/src/racket/src/thread.c | 10 +- 18 files changed, 1332 insertions(+), 386 deletions(-) diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index c85728fa02..8918b1c225 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.3.0.1") +(define version "6.3.0.2") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/scribblings/reference/memory.scrbl b/pkgs/racket-doc/scribblings/reference/memory.scrbl index 1fd3e970b8..740124e485 100644 --- a/pkgs/racket-doc/scribblings/reference/memory.scrbl +++ b/pkgs/racket-doc/scribblings/reference/memory.scrbl @@ -287,27 +287,45 @@ collection mode, the text has the format ]} -@defproc[(collect-garbage [request (or/c 'major 'minor) 'major]) void?]{ +@defproc[(collect-garbage [request (or/c 'major 'minor 'incremental) 'major]) void?]{ -Forces an immediate @tech{garbage collection} (unless garbage -collection is disabled by setting @envvar{PLTDISABLEGC}). Some -effectively unreachable data may remain uncollected, because the -collector cannot prove that it is unreachable. +Requests an immediate @tech{garbage collection} or requests a +garbage-collection mode, depending on @racket[request]: -The @racket[collect-garbage] procedure provides some control over the -timing of collections, but garbage will obviously be collected even if -this procedure is never called (unless garbage collection is disabled). +@itemlist[ -If @racket[request] is @racket['major], then a major collection is -run. If @racket[request] is @racket['minor], then either a minor -collection is run or no collection is run (and no -collection occurs when @racket[(system-type 'gc)] returns -@racket['cgc] or when a normally scheduled minor collection would -cause a major collection); minor collections triggered by -@racket[collect-garbage] do not cause major collections to run any -sooner than they would have otherwise. + @item{@racket['major] --- Forces a ``major'' collection, which + inspects all memory. Some effectively unreachable data may + remain uncollected, because the collector cannot prove that it + is unreachable. -@history[#:changed "6.3" @elem{Added the @racket[request] argument.}]} + This mode of @racket[collect-garbage] procedure provides some + control over the timing of collections, but garbage will + obviously be collected even if this procedure is never + called---unless garbage collection is disabled by setting + @envvar{PLTDISABLEGC}.} + + @item{@racket['minor] --- Requests a ``minor'' collection, which + mostly inspects only recent allocations. If minor collection is + not supported (e.g., when @racket[(system-type 'gc)] returns + @racket['cgc]) or if the next collection must be a major + collection, no collection is performed. More generally, minor collections + triggered by @racket[(collect-garbage 'minor)] do not cause + major collections any sooner than they would occur otherwise.} + + @item{@racket['incremental] --- Requests that each minor + collection performs incremental work toward a major collection. + This incremental-mode request expires at the next major + collection. + + The intent of incremental mode is to significantly reduce pause + times due to major collections, but incremental mode typically + implies longer minor-collection times and higher memory use.} + +] + +@history[#:changed "6.3" @elem{Added the @racket[request] argument.} + #:changed "6.3.0.2" @elem{Added @racket['incremental] mode.}]} @defproc[(current-memory-use [cust custodian? #f]) exact-nonnegative-integer?]{ diff --git a/racket/src/racket/gc2/README b/racket/src/racket/gc2/README index 18b070bbd2..f8cf64b87d 100644 --- a/racket/src/racket/gc2/README +++ b/racket/src/racket/gc2/README @@ -80,6 +80,17 @@ address GC_resolve returns the same address. A GC_is_marked operation reports whether an object at its old address has been marked; it works only on old addresses. +Normally, the mark function for an object is called only when the +object is first marked in a given GC pass. When generational +collection, the mark function can be called for an old-generation +object if it potentially changed since a previous collection; still, +the mark function will be called only once during that collection, so +it's as if the object were in the new generation. With incremental +collection, however, a macro procedure can be called due to changes +even if the object is already incrementally marked as an +old-generaiton object. The GC_current_mode() function reports the +current mode for a given call to the marking function. + Memory Kinds ------------ diff --git a/racket/src/racket/gc2/commongc_internal.h b/racket/src/racket/gc2/commongc_internal.h index 652d367a3a..e2e570a0bc 100644 --- a/racket/src/racket/gc2/commongc_internal.h +++ b/racket/src/racket/gc2/commongc_internal.h @@ -20,6 +20,7 @@ typedef struct GC_Weak_Array { void *replace_val; struct GC_Weak_Array *next; void *data[1]; /* must be the 5th longword! */ + /* inc_next is after the array */ } GC_Weak_Array; /* The GC_Weak_Box struct is not externally visible, but @@ -32,6 +33,7 @@ typedef struct GC_Weak_Box { void **secondary_erase; int soffset, is_late; struct GC_Weak_Box *next; + struct GC_Weak_Box *inc_next; } GC_Weak_Box; /* The GC_Ephemeron struct is not externally visible, but @@ -43,6 +45,7 @@ typedef struct GC_Ephemeron { void *val; /* The rest is up to us: */ struct GC_Ephemeron *next; + struct GC_Ephemeron *inc_next; } GC_Ephemeron; typedef struct GC_Immobile_Box { diff --git a/racket/src/racket/gc2/fnls.c b/racket/src/racket/gc2/fnls.c index 4a893e56b5..1eb83396f2 100644 --- a/racket/src/racket/gc2/fnls.c +++ b/racket/src/racket/gc2/fnls.c @@ -119,7 +119,7 @@ void GC_set_finalizer(void *p, int tagged, int level, void (*f)(void *p, void *d data = gc->park[1]; gc->park[0] = NULL; gc->park[1] = NULL; - + fnl->p = p; fnl->f = f; fnl->data = data; @@ -174,9 +174,14 @@ static void reset_finalizer_tree(GCTYPE *gc) for (; fnl; fnl = next) { next = fnl->next; - if (is_in_gen_half(fnl, gc) - || is_in_gen_half(fnl->f, gc) - || is_in_gen_half(fnl->data, gc)) + /* Checking both `fnl` and `fnl->p` is redundant, since + `fnl` is always allocated after `fnl->p`, but check + both just in case the order of allocation somehow + changes in the future. */ + if (is_in_generation_half(gc, fnl) + || is_in_generation_half(gc, fnl->f) + || is_in_generation_half(gc, fnl->p) + || is_in_generation_half(gc, fnl->data)) add_finalizer(fnl, 1, gc); else add_finalizer(fnl, 0, gc); diff --git a/racket/src/racket/gc2/gc2.h b/racket/src/racket/gc2/gc2.h index 9519db0e1b..db6adf9edb 100644 --- a/racket/src/racket/gc2/gc2.h +++ b/racket/src/racket/gc2/gc2.h @@ -168,6 +168,10 @@ GC2_EXTERN void GC_enable_collection(int on); /* Performs an immediate (full) collection. */ +GC2_EXTERN void GC_request_incremental_mode(void); +/* + Requests incremental mode; lasts until the next major collection. */ + GC2_EXTERN void GC_free_all(void); /* Releases all memory, removes all signal handlers, etc. @@ -372,9 +376,33 @@ GC2_EXTERN int GC_is_marked2(const void *p, struct NewGC *gc); /* Reports whether p has been marked. */ +GC2_EXTERN int GC_current_mode(struct NewGC *gc); +# define GC_CURRENT_MODE_MINOR 0 +# define GC_CURRENT_MODE_MAJOR 1 +# define GC_CURRENT_MODE_INCREMENTAL 2 +# define GC_CURRENT_MODE_BACKPOINTER_REMARK 3 +# define GC_CURRENT_MODE_ACCOUNTING 4 +/* + The mode during a mark or fixup function callback. + The GC_CURRENT_MODE_BACKPOINTER_REMARK mode corresponds + to re-traversing an old-generation object that was + formerly marked but has been mutated. */ + GC2_EXTERN int GC_is_partial(struct NewGC *gc); /* - Reports whether the current GC is a non-full collection. */ + Reports whether the current GC is a non-full collection + or accounting pass. GC_current_mode() is better. */ + +GC2_EXTERN int GC_started_incremental(struct NewGC *gc); +/* + Reports whether the current GC uses incremental collection. */ + +GC2_EXTERN void *GC_malloc_for_incremental(size_t amt); +/* + Use only when GC_started_incremental(); allocates + atomic memory that will be released at the end of the + next full collection, which ends the current + incremental pass. */ GC2_EXTERN void GC_mark_no_recur(struct NewGC *gc, int enable); GC2_EXTERN void GC_retract_only_mark_stack_entry(void *pf, struct NewGC *gc); diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 7a3d0dd881..fb13cf1b59 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -148,6 +148,8 @@ inline static int custodian_to_owner_set(NewGC *gc,Scheme_Custodian *cust) { int i; + GC_ASSERT(SAME_TYPE(SCHEME_TYPE(cust), scheme_custodian_type)); + if (cust->gc_owner_set) return cust->gc_owner_set; @@ -356,7 +358,7 @@ inline static void BTC_memory_account_mark(NewGC *gc, mpage *page, void *ptr, in if(info->btc_mark == gc->old_btc_mark) { info->btc_mark = gc->new_btc_mark; account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(page->size), is_a_master_page); - push_ptr(gc, TAG_AS_BIG_PAGE_PTR(ptr)); + push_ptr(gc, TAG_AS_BIG_PAGE_PTR(ptr), 0); } } else { /* medium page */ @@ -366,7 +368,7 @@ inline static void BTC_memory_account_mark(NewGC *gc, mpage *page, void *ptr, in info->btc_mark = gc->new_btc_mark; account_memory(gc, gc->current_mark_owner, info->size, is_a_master_page); ptr = OBJHEAD_TO_OBJPTR(info); - push_ptr(gc, ptr); + push_ptr(gc, ptr, 0); } } } else { @@ -375,7 +377,7 @@ inline static void BTC_memory_account_mark(NewGC *gc, mpage *page, void *ptr, in if(info->btc_mark == gc->old_btc_mark) { info->btc_mark = gc->new_btc_mark; account_memory(gc, gc->current_mark_owner, info->size, 0); - push_ptr(gc, ptr); + push_ptr(gc, ptr, 0); } } } @@ -464,9 +466,9 @@ static void propagate_accounting_marks(NewGC *gc) { void *p; - while(pop_ptr(gc, &p) && !gc->kill_propagation_loop) { + while(pop_ptr(gc, &p, 0) && !gc->kill_propagation_loop) { /* GCDEBUG((DEBUGOUTF, "btc_account: popped off page %p:%p, ptr %p\n", page, page->addr, p)); */ - propagate_marks_worker(gc, p); + propagate_marks_worker(gc, p, 0); } if(gc->kill_propagation_loop) reset_pointer_stack(gc); @@ -499,6 +501,8 @@ static void BTC_do_accounting(NewGC *gc) Scheme_Custodian_Reference *box = cur->global_next; int i; + GC_ASSERT(SAME_TYPE(SCHEME_TYPE(cur), scheme_custodian_type)); + GCDEBUG((DEBUGOUTF, "\nBEGINNING MEMORY ACCOUNTING\n")); gc->doing_memory_accounting = 1; gc->in_unsafe_allocation_mode = 1; @@ -518,6 +522,7 @@ static void BTC_do_accounting(NewGC *gc) /* start with root: */ while (cur->parent && SCHEME_PTR1_VAL(cur->parent)) { cur = SCHEME_PTR1_VAL(cur->parent); + GC_ASSERT(SAME_TYPE(SCHEME_TYPE(cur), scheme_custodian_type)); } /* walk forward for the order we want (blame parents instead of children) */ @@ -537,7 +542,8 @@ static void BTC_do_accounting(NewGC *gc) propagate_accounting_marks(gc); last = cur; - box = cur->global_next; cur = box ? SCHEME_PTR1_VAL(box) : NULL; + box = cur->global_next; + cur = box ? SCHEME_PTR1_VAL(box) : NULL; owner_table = gc->owner_table; owner_table[owner]->memory_use = add_no_overflow(owner_table[owner]->memory_use, diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 0e21459459..cbf66a94c9 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -79,7 +79,7 @@ enum { SIZE_CLASS_SMALL_PAGE = 0, /* can be a nursery page */ SIZE_CLASS_MED_PAGE = 1, SIZE_CLASS_BIG_PAGE = 2, - SIZE_CLASS_BIG_PAGE_MARKED = 3, + SIZE_CLASS_BIG_PAGE_MARKED = 3 }; enum { @@ -237,11 +237,20 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { #define GEN0_MAX_SIZE (32 * 1024 * 1024) #define GEN0_PAGE_SIZE (1 * 1024 * 1024) +/* Run a full collection when the current memory use is more than + FULL_COLLECTION_SIZE_RATIO times the memory use after the previous + full collection. */ +#define FULL_COLLECTION_SIZE_RATIO 2 + /* Whether to use a little aging, moving gen-0 objects to a gen-1/2 space; by default, enabled when memory use is high enough: */ #define AGE_GEN_0_TO_GEN_HALF(gc) ((gc)->memory_in_use > (GEN0_MAX_SIZE * 8)) +/* Incremental mode */ +#define ALWAYS_COLLECT_INCREMENTAL_ON_MINOR 0 +#define INCREMENTAL_COLLECT_FUEL (16 * 1024) + /* Conservatively force a major GC after a certain number of minor GCs. It should be ok to set this value arbitraily high. An earlier value of 100, meanwhile, @@ -977,6 +986,12 @@ static void collect_now(NewGC *gc, int major, int nomajor) int again; do { if (!gc->dont_master_gc_until_child_registers && master_wants_to_collect()) { + if (gc->started_incremental) { + /* incremental state doesn't support references to the master + space, so finish up the one in progress so the next one starts + fresh */ + garbage_collect(gc, 1, 0, 0, NULL); + } wait_until_master_in_progress(gc); gc->major_places_gc = 1; garbage_collect(gc, 1, 0, 0, NULL); /* waits until all are done */ @@ -1993,10 +2008,10 @@ inline static void clean_gen_half(NewGC *gc) } -inline static mpage *pagemap_find_page_for_marking(NewGC *gc, const void *p) { +inline static mpage *pagemap_find_page_for_marking(NewGC *gc, const void *p, int get_gen1) { mpage *page; page = pagemap_find_page(gc->page_maps, p); - if (page && !gc->gc_full && (page->generation >= AGE_GEN_1)) return NULL; + if (page && !get_gen1 && (page->generation >= AGE_GEN_1)) return NULL; return page; } @@ -2009,8 +2024,10 @@ inline static int marked(NewGC *gc, const void *p) { mpage *page; + GC_ASSERT(!gc->check_gen1 || gc->gc_full || gc->inc_gen1); + if(!p) return 0; - if(!(page = pagemap_find_page_for_marking(gc, p))) return 1; + if(!(page = pagemap_find_page_for_marking(gc, p, gc->check_gen1))) return 1; switch(page->size_class) { case SIZE_CLASS_BIG_PAGE_MARKED: return 1; @@ -2021,19 +2038,46 @@ inline static int marked(NewGC *gc, const void *p) } /* else FALLTHROUGH */ case SIZE_CLASS_MED_PAGE: /* FALLTHROUGH */ - case SIZE_CLASS_BIG_PAGE: return OBJPTR_TO_OBJHEAD(p)->mark; break; + case SIZE_CLASS_BIG_PAGE: + return 0; + break; default: fprintf(stderr, "ABORTING! INVALID SIZE_CLASS %i\n", page->size_class); abort(); } } +static int is_in_generation_half(NewGC *gc, const void *p) +{ + mpage *page; + if (gc->gc_full) return 0; + page = pagemap_find_page_for_marking(gc, p, 1); + if (!page) return 0; + GC_ASSERT((page->generation == AGE_GEN_1) + || (page->generation == AGE_GEN_HALF)); + return page->generation == AGE_GEN_HALF; +} + int GC_is_marked2(const void *p, struct NewGC *gc) { return marked(gc, p); } +int GC_current_mode(struct NewGC *gc) +{ + if (gc->during_backpointer) + return GC_CURRENT_MODE_BACKPOINTER_REMARK; + else if (gc->doing_memory_accounting) + return GC_CURRENT_MODE_ACCOUNTING; + else if (gc->gc_full) + return GC_CURRENT_MODE_MAJOR; + else if (gc->inc_gen1) + return GC_CURRENT_MODE_INCREMENTAL; + else + return GC_CURRENT_MODE_MINOR; +} + /*****************************************************************************/ /* Internal Debugging Routines */ /*****************************************************************************/ @@ -2367,18 +2411,6 @@ static int is_finalizable_page(NewGC *gc, void *p) return !!pagemap_find_page(gc->page_maps, p); } -static int is_in_gen_half(void *p, NewGC *gc) -{ - mpage *page; - - if (gc->gc_full) - return 0; - - page = pagemap_find_page(gc->page_maps, p); - - return (page && (page->generation == AGE_GEN_HALF)); -} - #include "fnls.c" inline static void mark_finalizer_structs(NewGC *gc) @@ -2476,6 +2508,8 @@ inline static void check_finalizers(NewGC *gc, int level) /* weak boxes and arrays */ /*****************************************************************************/ +static void check_incremental_unprotect(NewGC *gc, mpage *page); + #define is_marked(gc, p) marked(gc, p) #define weak_box_resolve(p) GC_resolve(p) #include "weak.c" @@ -2518,8 +2552,8 @@ static int fixup_phantom(void *p, struct NewGC *gc) the standard C stack because we'll blow it; propagation makes for a *very* deep stack. So we use this instead. */ -#define MARK_STACK_START(ms) ((void **)(void *)&ms[1]) -#define MARK_STACK_END(ms) ((void **)((char *)ms + STACK_PART_SIZE)) +#define MARK_STACK_START(ms) ((void **)(void *)&(ms)[1]) +#define MARK_STACK_END(ms) ((void **)((char *)(ms) + STACK_PART_SIZE)) inline static MarkSegment* mark_stack_create_frame() { MarkSegment *mark_frame = (MarkSegment*)ofm_malloc(STACK_PART_SIZE); @@ -2536,7 +2570,32 @@ inline static void mark_stack_initialize(NewGC *gc) { } } -static void push_ptr(NewGC *gc, void *ptr) +static void push_ptr_at(void *ptr, MarkSegment **_mark_stack) +{ + MarkSegment *mark_stack = *_mark_stack; + + /* This happens during propagation if we go past the end of this MarkSegment*/ + if(mark_stack->top == MARK_STACK_END(mark_stack)) { + /* test to see if we already have another stack page ready */ + if(mark_stack->next) { + /* we do, so just use it */ + mark_stack = mark_stack->next; + mark_stack->top = MARK_STACK_START(mark_stack); + *_mark_stack = mark_stack; + } else { + /* we don't, so we need to allocate one */ + mark_stack->next = mark_stack_create_frame(); + mark_stack->next->prev = mark_stack; + mark_stack = mark_stack->next; + *_mark_stack = mark_stack; + } + } + + /* at this point, we're guaranteed to be good to push pointers */ + *(mark_stack->top++) = ptr; +} + +static void push_ptr(NewGC *gc, void *ptr, int inc_gen1) { #if 0 /* detect a bad pointer when it's pushed, instead of when it's popped: */ @@ -2567,32 +2626,21 @@ static void push_ptr(NewGC *gc, void *ptr) } } #endif - - /* This happens during propagation if we go past the end of this MarkSegment*/ - if(gc->mark_stack->top == MARK_STACK_END(gc->mark_stack)) { - /* test to see if we already have another stack page ready */ - if(gc->mark_stack->next) { - /* we do, so just use it */ - gc->mark_stack = gc->mark_stack->next; - gc->mark_stack->top = MARK_STACK_START(gc->mark_stack); - } else { - /* we don't, so we need to allocate one */ - gc->mark_stack->next = mark_stack_create_frame(); - gc->mark_stack->next->prev = gc->mark_stack; - gc->mark_stack = gc->mark_stack->next; - } - } - /* at this point, we're guaranteed to be good to push pointers */ - *(gc->mark_stack->top++) = ptr; + GC_ASSERT(inc_gen1 || !gc->inc_gen1); + + push_ptr_at(ptr, inc_gen1 ? &gc->inc_mark_stack : &gc->mark_stack); } -inline static int pop_ptr(NewGC *gc, void **ptr) +inline static int pop_ptr_at(void **ptr, MarkSegment **_mark_stack) { - if(gc->mark_stack->top == MARK_STACK_START(gc->mark_stack)) { - if(gc->mark_stack->prev) { + MarkSegment *mark_stack = *_mark_stack; + + if(mark_stack->top == MARK_STACK_START(mark_stack)) { + if(mark_stack->prev) { /* if there is a previous page, go to it */ - gc->mark_stack = gc->mark_stack->prev; + mark_stack = mark_stack->prev; + *_mark_stack = mark_stack; } else { /* if there isn't a previous page, then we've hit the bottom of the stack */ return 0; @@ -2600,10 +2648,15 @@ inline static int pop_ptr(NewGC *gc, void **ptr) } /* if we get here, we're guaranteed to have data */ - *ptr = *(--gc->mark_stack->top); + *ptr = *(--mark_stack->top); return 1; } +inline static int pop_ptr(NewGC *gc, void **ptr, int inc_gen1) +{ + return pop_ptr_at(ptr, inc_gen1 ? &gc->inc_mark_stack : &gc->mark_stack); +} + void GC_mark_no_recur(struct NewGC *gc, int enable) { if (enable) @@ -2615,18 +2668,52 @@ void GC_mark_no_recur(struct NewGC *gc, int enable) void GC_retract_only_mark_stack_entry(void *pf, struct NewGC *gc) { void *p2; - if (!pop_ptr(gc, &p2)) + if (!pop_ptr(gc, &p2, gc->inc_gen1)) p2 = NULL; if (REMOVE_BIG_PAGE_PTR_TAG(p2) != pf) { printf("internal error: cannot retract intended pointer: %p != %p\n", p2, pf); abort(); } - if (pop_ptr(gc, &p2)) { + if (pop_ptr(gc, &p2, gc->inc_gen1)) { printf("internal error: mark stack contained pointer other than retracted\n"); abort(); } } +static void merge_incremental_mark_stack(NewGC *gc) +{ + if(gc->inc_mark_stack) { + MarkSegment *inc_mark_stack = gc->inc_mark_stack, *mark_stack = gc->mark_stack; + + while (inc_mark_stack->next) + inc_mark_stack = inc_mark_stack->next; + while (mark_stack->prev) mark_stack = mark_stack->prev; + + while (inc_mark_stack + && (inc_mark_stack->top == MARK_STACK_START(inc_mark_stack))) { + MarkSegment *m = inc_mark_stack; + inc_mark_stack = m->prev; + if (inc_mark_stack) + inc_mark_stack->next = NULL; + ofm_free(m, STACK_PART_SIZE); + } + + if (inc_mark_stack) { + mark_stack->prev = inc_mark_stack; + inc_mark_stack->next = mark_stack; + } + + gc->inc_mark_stack = NULL; + } +} + +static void incremental_mark_stack_initialize(NewGC *gc) { + if(!gc->inc_mark_stack) { + gc->inc_mark_stack = mark_stack_create_frame(); + gc->inc_mark_stack->prev = NULL; + } +} + inline static void clear_stack_pages(NewGC *gc) { if(gc->mark_stack) { @@ -2652,20 +2739,29 @@ inline static void clear_stack_pages(NewGC *gc) } } -inline static void free_all_stack_pages(NewGC *gc) +static void free_stack_pages_at(MarkSegment *mark_stack) { - if(gc->mark_stack) { + if (mark_stack) { MarkSegment *temp; /* go to the head of the list */ - for(; gc->mark_stack->prev; gc->mark_stack = gc->mark_stack->prev) {} + for (; mark_stack->prev; mark_stack = mark_stack->prev) {} /* then go through and clear them out */ - for(; gc->mark_stack; gc->mark_stack = temp) { - temp = gc->mark_stack->next; - ofm_free(gc->mark_stack, STACK_PART_SIZE); + for (; mark_stack; mark_stack = temp) { + temp = mark_stack->next; + ofm_free(mark_stack, STACK_PART_SIZE); } } + } + +inline static void free_all_stack_pages(NewGC *gc) +{ + free_stack_pages_at(gc->mark_stack); + gc->mark_stack = NULL; + free_stack_pages_at(gc->inc_mark_stack); + gc->inc_mark_stack = NULL; } + inline static void reset_pointer_stack(NewGC *gc) { /* go to the head of the list */ @@ -2674,12 +2770,60 @@ inline static void reset_pointer_stack(NewGC *gc) gc->mark_stack->top = MARK_STACK_START(gc->mark_stack); } -static inline void propagate_marks_worker(NewGC *gc, void *p); +size_t align_round_up(size_t amt) +{ + while (amt & CHECK_ALIGN_MASK) + amt++; + return amt; +} + +void *GC_malloc_for_incremental(size_t amt) +{ + NewGC *gc = GC_get_GC(); + void *p; + + amt = align_round_up(amt); + + if (!gc->inc_space || ((gc->inc_space->size - gc->inc_space->pos) < amt)) { + size_t sz, pos; + pos = align_round_up(sizeof(Inc_Admin_Page)); + sz = amt + pos; + if (sz < 1024) + sz = 1024; + + p = ofm_malloc(sz); + + ((Inc_Admin_Page *)p)->next = gc->inc_space; + gc->inc_space = (Inc_Admin_Page *)p; + gc->inc_space->size = sz; + gc->inc_space->pos = pos; + } + + p = (char *)(gc->inc_space) + gc->inc_space->pos; + + gc->inc_space->pos += amt; + + return p; +} + +static void free_incremental_admin_pages(NewGC *gc) +{ + Inc_Admin_Page *p, *next; + + for (p = gc->inc_space; p; p = next) { + next = p->next; + ofm_free(p, p->size); + } + + gc->inc_space = NULL; +} /*****************************************************************************/ /* MEMORY ACCOUNTING */ /*****************************************************************************/ +static inline void propagate_marks_worker(NewGC *gc, void *pp, int inc_gen1); + #ifdef NEWGC_BTC_ACCOUNT # include "mem_account.c" #else @@ -2788,6 +2932,12 @@ static int designate_modified_gc(NewGC *gc, void *p) mpage *page = pagemap_find_page(gc->page_maps, p); if (gc->no_further_modifications) { + if (page && (page->generation >= AGE_GEN_1) && gc->inc_gen1 && page->mprotected) { + /* Some marking functions, like the one for weak boxes, + update the record, so it's ok to make the page writable. */ + check_incremental_unprotect(gc, page); + return 1; + } GCPRINT(GCOUTF, "Seg fault (internal error during gc) at %p\n", p); return 0; } @@ -3095,6 +3245,7 @@ static void NewGC_initialize(NewGC *newgc, NewGC *inheritgc, NewGC *parentgc) { newgc->generations_available = 1; newgc->last_full_mem_use = (20 * 1024 * 1024); + newgc->inc_mem_use_threshold = (FULL_COLLECTION_SIZE_RATIO * newgc->inc_mem_use_threshold); newgc->new_btc_mark = 1; newgc->place_memory_limit = (uintptr_t)(intptr_t)-1; @@ -3211,7 +3362,6 @@ void GC_destruct_child_gc() { free_child_gc(); } - static inline void save_globals_to_gc(NewGC *gc) { gc->saved_GC_variable_stack = GC_variable_stack; gc->saved_GC_gen0_alloc_page_ptr = GC_gen0_alloc_page_ptr; @@ -3312,6 +3462,13 @@ void GC_gcollect_minor(void) collect_now(gc, 0, 1); } +void GC_request_incremental_mode(void) +{ + NewGC *gc = GC_get_GC(); + + gc->incremental_requested = 1; +} + void GC_enable_collection(int on) { NewGC *gc = GC_get_GC(); @@ -3372,6 +3529,44 @@ intptr_t GC_get_memory_use(void *o) /* Garbage collection proper ... and all the mess therein */ /*****************************************************************************/ +static void check_incremental_unprotect(NewGC *gc, mpage *page) +{ + /* must be due to incremental GC */ + GC_ASSERT(!gc->gc_full); + GC_ASSERT(gc->mark_gen1); + + if (page->mprotected) { + page->mprotected = 0; + mmu_write_unprotect_page(gc->mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); + page->reprotect_next = gc->reprotect_next; + gc->reprotect_next = page; + page->reprotect = 1; /* in case this page is used to hold moved gen0 objects */ + } +} + +static void page_newly_marked_on(NewGC *gc, mpage *page, int is_a_master_page, int inc_gen1) +{ + if (inc_gen1) { + GC_ASSERT(!page->inc_marked_on); + page->inc_marked_on = 1; + page->inc_modified_next = gc->inc_modified_next; + gc->inc_modified_next = page; + } else { + GC_ASSERT(!page->marked_on); + page->marked_on = 1; + if (!is_a_master_page && !page->marked_from) { + page->modified_next = gc->modified_next; + gc->modified_next = page; + } + } +} + +static void page_marked_on(NewGC *gc, mpage *page, int is_a_master_page, int inc_gen1) +{ + if (inc_gen1 ? !page->inc_marked_on : !page->marked_on) + page_newly_marked_on(gc, page, is_a_master_page, inc_gen1); +} + static void promote_marked_gen0_big_page(NewGC *gc, mpage *page) { page->generation = AGE_GEN_1; @@ -3397,11 +3592,11 @@ static void promote_marked_gen0_big_page(NewGC *gc, mpage *page) { #endif } -static void mark_recur_or_push_ptr(struct NewGC *gc, void *p, int is_a_master_page) +static void mark_recur_or_push_ptr(struct NewGC *gc, void *p, int is_a_master_page, int inc_gen1) { objhead *ohead = OBJPTR_TO_OBJHEAD(p); - if ((gc->mark_depth < MAX_RECUR_MARK_DEPTH) && !is_a_master_page) { + if ((gc->mark_depth < MAX_RECUR_MARK_DEPTH) && !is_a_master_page && !inc_gen1) { switch (ohead->type) { case PAGE_TAGGED: { @@ -3431,7 +3626,7 @@ static void mark_recur_or_push_ptr(struct NewGC *gc, void *p, int is_a_master_pa } } - push_ptr(gc, p); + push_ptr(gc, p, inc_gen1); } /* This is the first mark routine. It's a bit complicated. */ @@ -3446,7 +3641,7 @@ void GC_mark2(void *pp, struct NewGC *gc) return; } - if(!(page = pagemap_find_page_for_marking(gc, p))) { + if(!(page = pagemap_find_page_for_marking(gc, p, gc->mark_gen1))) { #ifdef MZ_USE_PLACES if (gc->major_places_gc && (page = pagemap_find_page(MASTERGC->page_maps, p))) { is_a_master_page = 1; @@ -3472,7 +3667,9 @@ void GC_mark2(void *pp, struct NewGC *gc) } #endif - GC_ASSERT(!page->marked_from); + GC_ASSERT(!page->marked_from + || (gc->mark_gen1 && !gc->gc_full) + || (gc->gc_full && gc->during_backpointer)); /* MED OR BIG PAGE */ if (page->size_class) { @@ -3480,6 +3677,7 @@ void GC_mark2(void *pp, struct NewGC *gc) if (page->size_class > SIZE_CLASS_MED_PAGE) { /* This is a bigpage. The first thing we do is see if its been marked previously */ + int inc_gen1; if (page->size_class != SIZE_CLASS_BIG_PAGE) { GCDEBUG((DEBUGOUTF, "Not marking %p on big %p (already marked)\n", p, page)); RELEASE_PAGE_LOCK(is_a_master_page, page); @@ -3489,41 +3687,48 @@ void GC_mark2(void *pp, struct NewGC *gc) page->size_class = SIZE_CLASS_BIG_PAGE_MARKED; /* if this is in the nursery, we want to move it out of the nursery */ - if((page->generation == AGE_GEN_0) && !is_a_master_page) + if((page->generation == AGE_GEN_0) && !is_a_master_page) { + GC_ASSERT(!gc->inc_gen1); promote_marked_gen0_big_page(gc, page); + inc_gen1 = 0; + } else if (gc->gc_full || is_a_master_page) + inc_gen1 = 0; + else + inc_gen1 = 1; - GC_ASSERT(!page->marked_on); - page->marked_on = 1; - if (!is_a_master_page) { - page->modified_next = gc->modified_next; - gc->modified_next = page; - } + page_newly_marked_on(gc, page, is_a_master_page, inc_gen1); record_backtrace(gc, page, BIG_PAGE_TO_OBJECT(page)); GCDEBUG((DEBUGOUTF, "Marking %p on big page %p\n", p, page)); /* Finally, we want to add this to our mark queue, so we can propagate its pointers */ - push_ptr(gc, TAG_AS_BIG_PAGE_PTR(p)); + push_ptr(gc, TAG_AS_BIG_PAGE_PTR(p), inc_gen1); } else { /* A medium page. */ objhead *info = MED_OBJHEAD(p, page->obj_size); + int inc_gen1; if (info->mark) { GCDEBUG((DEBUGOUTF,"Not marking %p (already marked)\n", p)); RELEASE_PAGE_LOCK(is_a_master_page, page); return; } - info->mark = 1; - if (!page->marked_on) { - page->marked_on = 1; - if (!is_a_master_page) { - page->modified_next = gc->modified_next; - gc->modified_next = page; + if ((page->generation == AGE_GEN_0) || gc->gc_full) { + GC_ASSERT(!gc->inc_gen1); + inc_gen1 = 0; + } else { + if (is_a_master_page) + inc_gen1 = 0; + else { + inc_gen1 = 1; + check_incremental_unprotect(gc, page); } } + info->mark = 1; + page_marked_on(gc, page, is_a_master_page, inc_gen1); p = OBJHEAD_TO_OBJPTR(info); backtrace_new_page_if_needed(gc, page); record_backtrace(gc, page, p); - mark_recur_or_push_ptr(gc, p, is_a_master_page); + mark_recur_or_push_ptr(gc, p, is_a_master_page, inc_gen1); } } /* SMALL_PAGE from gen0 or gen1 */ @@ -3542,26 +3747,28 @@ void GC_mark2(void *pp, struct NewGC *gc) object */ if (page->generation >= AGE_GEN_1) { /* this is a generation 1 object. This means we are not going - to move it, we don't have to check to see if it's an atomic + to move it now, we don't have to check to see if it's an atomic object masquerading as a tagged object, etc. So all we do is add the pointer to the mark queue and note on the page - that we marked something on it*/ + that we marked something on it */ + int inc_gen1; if ((NUM(page->addr) + page->scan_boundary) <= NUM(p)) { + GC_ASSERT(!gc->inc_gen1); GCDEBUG((DEBUGOUTF, "Marking %p (leaving alone)\n", p)); - ohead->mark = 1; - if (!page->marked_on) { - page->marked_on = 1; - if (!is_a_master_page) { - page->modified_next = gc->modified_next; - gc->modified_next = page; - } - } - page->live_size += ohead->size; - record_backtrace(gc, page, p); - mark_recur_or_push_ptr(gc, p, is_a_master_page); + inc_gen1 = 0; } else { GCDEBUG((DEBUGOUTF, "Not marking %p (it's old; %p / %i)\n", p, page, page->scan_boundary)); + if (is_a_master_page) { + inc_gen1 = 0; + } else { + check_incremental_unprotect(gc, page); + inc_gen1 = 1; + } } + ohead->mark = 1; + page_marked_on(gc, page, is_a_master_page, inc_gen1); + record_backtrace(gc, page, p); + mark_recur_or_push_ptr(gc, p, is_a_master_page, inc_gen1); } else { /* this is a generation 0 or 1/2 object. This means that we do have to do all of the above. Fun, fun, fun. */ @@ -3571,6 +3778,8 @@ void GC_mark2(void *pp, struct NewGC *gc) objhead *newplace; int new_type; + GC_ASSERT(!gc->inc_gen1); + /* first check to see if this is an atomic object masquerading as a tagged object; if it is, then convert it */ if(type == PAGE_TAGGED) { @@ -3676,7 +3885,7 @@ void GC_mark2(void *pp, struct NewGC *gc) GCDEBUG((DEBUGOUTF,"Marking %p (moved to %p on page %p)\n", p, newp, work)); *(void**)p = newp; *(void **)pp = newp; - mark_recur_or_push_ptr(gc, newp, is_a_master_page); + mark_recur_or_push_ptr(gc, newp, is_a_master_page, 0); } } } @@ -3689,37 +3898,8 @@ void GC_mark(void *pp) GC_mark2(pp, GC_get_GC()); } -/* this is the second mark routine. It's not quite as complicated. */ -/* this is what actually does mark propagation */ -static inline void propagate_marks_worker(NewGC *gc, void *pp) +static inline void mark_traverse_object(NewGC *gc, void **start, void **end, int alloc_type) { - void **start, **end; - int alloc_type; - void *p; - - /* we can assume a lot here -- like it's a valid pointer with a page -- - because we vet bad cases out in GC_mark, above */ - if (IS_BIG_PAGE_PTR(pp)) { - mpage *page; - p = REMOVE_BIG_PAGE_PTR_TAG(pp); - page = pagemap_find_page(gc->page_maps, p); -#ifdef MZ_USE_PLACES - if (!page && gc->major_places_gc) { - page = pagemap_find_page(MASTERGC->page_maps, p); - } -#endif - start = PPTR(BIG_PAGE_TO_OBJECT(page)); - alloc_type = page->page_type; - end = PAGE_END_VSS(page); - } else { - objhead *info; - p = pp; - info = OBJPTR_TO_OBJHEAD(p); - start = p; - alloc_type = info->type; - end = PPTR(info) + info->size; - } - set_backtrace_source(gc, start, alloc_type); switch(alloc_type) { @@ -3751,21 +3931,90 @@ static inline void propagate_marks_worker(NewGC *gc, void *pp) } } -static void propagate_marks(NewGC *gc) +/* this is the second mark routine. It's not quite as complicated. */ +/* this is what actually does mark propagation */ +static inline void propagate_marks_worker(NewGC *gc, void *pp, int inc_gen1) { + void **start, **end; + int alloc_type; void *p; - while(pop_ptr(gc, &p)) { - GCDEBUG((DEBUGOUTF, "Popped pointer %p\n", p)); - propagate_marks_worker(gc, p); + /* we can assume a lot here -- like it's a valid pointer with a page -- + because we vet bad cases out in GC_mark, above */ + if (IS_BIG_PAGE_PTR(pp)) { + mpage *page; + p = REMOVE_BIG_PAGE_PTR_TAG(pp); + page = pagemap_find_page(gc->page_maps, p); +#ifdef MZ_USE_PLACES + if (!page && gc->major_places_gc) { + page = pagemap_find_page(MASTERGC->page_maps, p); + } +#endif + start = PPTR(BIG_PAGE_TO_OBJECT(page)); + alloc_type = page->page_type; + end = PAGE_END_VSS(page); + GC_ASSERT(inc_gen1 || !page->mprotected); + } else { + objhead *info; + p = pp; + info = OBJPTR_TO_OBJHEAD(p); + start = p; + alloc_type = info->type; + end = PPTR(info) + info->size; } + + mark_traverse_object(gc, start, end, alloc_type); +} + +static void propagate_marks(NewGC *gc) +{ + void *p; + int prop_count = 0; + + while(pop_ptr(gc, &p, 0)) { + prop_count++; + GCDEBUG((DEBUGOUTF, "Popped pointer %p\n", p)); + propagate_marks_worker(gc, p, 0); + } + + gc->prop_count += prop_count; } static void propagate_marks_plus_ephemerons(NewGC *gc) { do { propagate_marks(gc); - } while (mark_ready_ephemerons(gc)); + } while (mark_ready_ephemerons(gc, 0)); +} + +static void propagate_incremental_marks(NewGC *gc, int fuel) +{ + if (gc->inc_mark_stack) { + int save_inc, save_mark, save_check, init_fuel = fuel; + + save_inc = gc->inc_gen1; + save_mark = gc->mark_gen1; + save_check = gc->check_gen1; + + gc->inc_gen1 = 1; + gc->mark_gen1 = 1; + gc->check_gen1 = 1; + + do { + void *p; + while (fuel && pop_ptr(gc, &p, 1)) { + GCDEBUG((DEBUGOUTF, "Popped incremental pointer %p\n", p)); + propagate_marks_worker(gc, p, 1); + fuel--; + } + } while (mark_ready_ephemerons(gc, 1) && fuel); + + gc->inc_prop_count += (init_fuel - fuel); + + gc->inc_gen1 = save_inc; + gc->mark_gen1 = save_mark; + gc->check_gen1 = save_check; + } } #ifdef MZ_USE_PLACES @@ -3786,7 +4035,7 @@ static void promote_marked_gen0_big_pages(NewGC *gc) void *GC_resolve2(void *p, NewGC *gc) { - mpage *page = pagemap_find_page_for_marking(gc, p); + mpage *page = pagemap_find_page_for_marking(gc, p, gc->check_gen1); objhead *info; if (!page || (page->size_class > SIZE_CLASS_SMALL_PAGE)) @@ -3809,6 +4058,11 @@ void *GC_fixup_self(void *p) return p; } +#define CHECK_NO_MISSED_FIXUPS 0 +#if CHECK_NO_MISSED_FIXUPS +static int disallow_fixups; +#endif + void GC_fixup2(void *pp, struct NewGC *gc) { mpage *page; @@ -3817,7 +4071,7 @@ void GC_fixup2(void *pp, struct NewGC *gc) if (!p || (NUM(p) & 0x1)) return; - page = pagemap_find_page_for_marking(gc, p); + page = pagemap_find_page_for_marking(gc, p, gc->mark_gen1); if (page) { objhead *info; @@ -3825,9 +4079,13 @@ void GC_fixup2(void *pp, struct NewGC *gc) if (page->size_class > SIZE_CLASS_SMALL_PAGE) return; info = OBJPTR_TO_OBJHEAD(p); - /* assert: info->moved => info->mark */ - /* !gc->gc_full => info->moved */ + GC_ASSERT(!info->dead); if (info->moved) { +#if CHECK_NO_MISSED_FIXUPS + GC_ASSERT(!disallow_fixups); +#endif + GC_ASSERT(!OBJPTR_TO_OBJHEAD(*(void **)p)->dead); + GC_ASSERT(!OBJPTR_TO_OBJHEAD(*(void **)p)->moved); *(void**)pp = *(void**)p; } else { GCDEBUG((DEBUGOUTF, "Not repairing %p from %p (not moved)\n",p,pp)); @@ -3853,12 +4111,16 @@ int GC_is_on_allocated_page(void *p) return !!pagemap_find_page(gc->page_maps, p); } - int GC_is_partial(struct NewGC *gc) { return !gc->gc_full || gc->doing_memory_accounting; } +int GC_started_incremental(struct NewGC *gc) +{ + return gc->started_incremental; +} + /*****************************************************************************/ /* memory stats and traces */ /*****************************************************************************/ @@ -4145,7 +4407,7 @@ void *GC_next_tagged_start(void *p) /* garbage collection */ /*****************************************************************************/ -static void reset_gen1_pages_live_and_scan_boundaries(NewGC *gc) +static void reset_gen1_pages_scan_boundaries(NewGC *gc) { mpage *work; int i; @@ -4161,7 +4423,6 @@ static void reset_gen1_pages_live_and_scan_boundaries(NewGC *gc) mmu_queue_write_unprotect_range(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); } } - work->live_size = 0; work->scan_boundary = PREFIX_SIZE; } } @@ -4180,6 +4441,19 @@ static void reset_gen1_pages_live_and_scan_boundaries(NewGC *gc) mmu_flush_write_unprotect_ranges(gc->mmu); } +static inline void mark_traverse_object_no_gen1(NewGC *gc, void **start, void **end, int alloc_type) +{ + if (gc->mark_gen1) { + /* In incremental mode, for a backpointer traversal of an unmarked + object, don't mark referenced old-generation objects; do that + only when the old-generation object is marked (if ever). */ + gc->mark_gen1 = 0; + mark_traverse_object(gc, start, end, alloc_type); + gc->mark_gen1 = 1; + } else + mark_traverse_object(gc, start, end, alloc_type); +} + static void mark_backpointers(NewGC *gc) { /* For a minor collection, we need to mark any pointers that point @@ -4192,67 +4466,133 @@ static void mark_backpointers(NewGC *gc) When a generation-1 page is added to the `modified_next` chain, it's old size is deducted from `memory_is_use`, and its size will - be added back during the repair pahse. */ + be added back during the repair pahse. - if (!gc->gc_full) { - mpage *work; - int traversed = 0; + For a major collection, we still to to traverse back-pointered + pages if any major-collection work was performed incrementally. + In that case, we use a special marking mode that indicates for + re-marking an object that has already been marked for a full + GC. */ - for (work = gc->modified_next; work; work = work->modified_next) { - GC_ASSERT(work->back_pointers); + mpage *work, *orig_modified_next; + int traversed = 0; - if (work->mprotected) { - /* expected only if QUEUED_MPROTECT_INFECTS_XXX && AGE_GEN_0_TO_GEN_HALF(gc) */ - work->mprotected = 0; - mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); - } + if (gc->gc_full && !gc->started_incremental) { + /* no need to traverse backpointers, because we're going to + traverse the whole heap */ + gc->modified_next = NULL; + return; + } - work->marked_from = 1; + GC_mark_no_recur(gc, 1); + gc->during_backpointer = 1; - if (work->size_class == SIZE_CLASS_BIG_PAGE) { - /* must be a big page */ - push_ptr(gc, TAG_AS_BIG_PAGE_PTR(BIG_PAGE_TO_OBJECT(work))); - gc->memory_in_use -= work->size; - } else if (work->size_class == SIZE_CLASS_SMALL_PAGE) { - /* small page */ - void **start = PAGE_START_VSS(work); - void **end = PAGE_END_VSS(work); + /* Set `marked_from` on all pages so that we don't try to + re-add them to the `modified_next` chain while marking: */ + for (work = gc->modified_next; work; work = work->modified_next) { + GC_ASSERT(work->back_pointers); + GC_ASSERT(!work->marked_from); + work->marked_from = 1; + } - GC_ASSERT(work->page_type != PAGE_ATOMIC); + orig_modified_next = gc->modified_next; + if (gc->gc_full) + gc->modified_next = NULL; + + for (work = orig_modified_next; work; work = work->modified_next) { + GC_ASSERT(work->back_pointers); + GC_ASSERT(work->marked_from); - while (start < end) { - objhead *info = (objhead *)start; - if (!info->dead) - push_ptr(gc, OBJHEAD_TO_OBJPTR(start)); - start += info->size; - } - gc->memory_in_use -= work->size; - } else { - /* medium page */ - void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); - void **end = PPTR(NUM(work->addr) + APAGE_SIZE - work->obj_size); - - GC_ASSERT(work->size_class == SIZE_CLASS_MED_PAGE); - - while (start <= end) { - objhead *info = (objhead *)start; - if (!info->dead) - push_ptr(gc, OBJHEAD_TO_OBJPTR(info)); - start += info->size; - } - - gc->memory_in_use -= work->live_size; - } - - traversed++; + if (work->mprotected) { + /* expected only if QUEUED_MPROTECT_INFECTS_XXX && AGE_GEN_0_TO_GEN_HALF(gc) */ + work->mprotected = 0; + mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block); } - gc->minor_old_traversed += traversed; - gc->minor_old_skipped += (gc->num_gen1_pages - traversed); - } else { - /* reset modified chain, since we assume no kept pages up front */ - gc->modified_next = NULL; + if (work->size_class >= SIZE_CLASS_BIG_PAGE) { + /* must be a big page */ + if (work->size_class == SIZE_CLASS_BIG_PAGE_MARKED) + mark_traverse_object(gc, PPTR(BIG_PAGE_TO_OBJECT(work)), PAGE_END_VSS(work), work->page_type); + else if (!gc->gc_full) + mark_traverse_object_no_gen1(gc, PPTR(BIG_PAGE_TO_OBJECT(work)), PAGE_END_VSS(work), work->page_type); + gc->memory_in_use -= work->size; + } else if (work->size_class == SIZE_CLASS_SMALL_PAGE) { + /* small page */ + void **start = PAGE_START_VSS(work); + void **end = (gc->gc_full + ? PAGE_END_VSS(work) + : (void**)((char *)work->addr + work->scan_boundary)); + + GC_ASSERT(work->page_type != PAGE_ATOMIC); + + while (start < end) { + objhead *info = (objhead *)start; + if (!info->dead) { + if (info->mark) + mark_traverse_object(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); + else if (!gc->gc_full) + mark_traverse_object_no_gen1(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); + } + start += info->size; + } + gc->memory_in_use -= work->size; + } else { + /* medium page */ + void **start = PPTR(NUM(work->addr) + PREFIX_SIZE); + void **end = PPTR(NUM(work->addr) + APAGE_SIZE - work->obj_size); + + GC_ASSERT(work->size_class == SIZE_CLASS_MED_PAGE); + + while (start <= end) { + objhead *info = (objhead *)start; + if (!info->dead) { + if (info->mark) + mark_traverse_object(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); + else if (!gc->gc_full) + mark_traverse_object_no_gen1(gc, PPTR(OBJHEAD_TO_OBJPTR(start)), PPTR(info) + info->size, info->type); + } + start += info->size; + } + + gc->memory_in_use -= work->live_size; + } + + traversed++; } + + if (gc->gc_full) { + /* move any marked_on backpointer page to new modified_next chain: */ + mpage *next; + for (work = orig_modified_next; work; work = next) { + GC_ASSERT(work->back_pointers); + GC_ASSERT(work->marked_from); + next = work->modified_next; + if (work->marked_on) { + work->modified_next = gc->modified_next; + gc->modified_next = work; + } + work->marked_from = 0; + } + + /* Move incremental modified pages to the `modified_next` chain: */ + for (work = gc->inc_modified_next; work; work = work->inc_modified_next) { + GC_ASSERT(work->inc_marked_on); + work->inc_marked_on = 0; + if (!work->marked_on) { + work->marked_on = 1; + work->modified_next = gc->modified_next; + gc->modified_next = work; + } + } + + gc->inc_modified_next = NULL; + } + + gc->during_backpointer = 0; + GC_mark_no_recur(gc, 0); + + gc->minor_old_traversed += traversed; + gc->minor_old_skipped += (gc->num_gen1_pages - traversed); } mpage *allocate_compact_target(NewGC *gc, mpage *work) @@ -4303,6 +4643,10 @@ inline static void do_heap_compact(NewGC *gc) { int i, compact_count = 0, noncompact_count = 0; int tic_tock = gc->num_major_collects % 2; + + /* incremental mode disables old-generation compaction: */ + if (gc->started_incremental) + return; mmu_prep_for_compaction(gc->mmu); @@ -4344,6 +4688,7 @@ inline static void do_heap_compact(NewGC *gc) objhead *info = (objhead *)start; if (info->mark) { + GC_ASSERT(!info->moved); while (avail <= info->size) { npage->size = NUM(newplace) - NUM(npage->addr); do { @@ -4478,116 +4823,76 @@ static void chain_marked_on_check(NewGC *gc) static void chain_marked_on_check(NewGC *gc) { } #endif -static void unmark_range(void **start, void **end) +static int unmark_range(void **start, void **end) { + int live_size = 0; + while(start < end) { objhead *info = (objhead *)start; - if (info->mark) + if (info->mark) { info->mark = 0; - else + live_size += info->size; + } else info->dead = 1; start += info->size; } + + return live_size; } -static void unmark_heap(NewGC *gc) -/* Set `dead` bit if not `mark`, otherwise clean `mark`. After this - pass, objects are live if `dead` is not set. */ -{ - mpage *page; - - /* See start of repair_heap() for more information on the current - page state. */ - - for (page = gc->modified_next; page; page = page->modified_next) { - GC_ASSERT(page->marked_on || page->marked_from); - if (page->generation == AGE_VACATED) { - /* this page will be released later */ - } else { - if (page->size_class >= SIZE_CLASS_BIG_PAGE) { - page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark, if any */ - } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { - GCDEBUG((DEBUGOUTF, "Unmarking objs on page %p, starting with %p\n", - page, start)); - unmark_range(PPTR(NUM(page->addr) + page->scan_boundary), - PAGE_END_VSS(page)); - - /* repair phase should walk the full page: */ - page->scan_boundary = PREFIX_SIZE; - } else { - GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); - if ((page->generation == AGE_GEN_0) || gc->gc_full) - unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), - PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); - } - } - } - - /* All gen-half pages count as modified: */ - for (page = gc->gen_half.pages; page; page = page->next) { - GC_ASSERT(page->generation == AGE_GEN_HALF); - unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), - PPTR(NUM(page->addr) + page->size - 1)); - } -} - -static int repair_mixed_page(NewGC *gc, mpage *page, void **end, int need_fixup) +static void repair_mixed_page(NewGC *gc, mpage *page, void **end) { void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); Fixup2_Proc *fixup_table = gc->fixup_table; - int non_dead = 0; while (start <= end) { objhead *info = (objhead *)start; if (!info->dead) { - non_dead++; - if (need_fixup) { - switch(info->type) { - case PAGE_ARRAY: - { - void **tempend = PPTR(info) + info->size, **tmpstart; - tmpstart = OBJHEAD_TO_OBJPTR(start); - while (tmpstart < tempend) gcFIXUP2(*tmpstart++, gc); - } - break; - case PAGE_TAGGED: - { - void *obj_start = OBJHEAD_TO_OBJPTR(start); - unsigned short tag = *(unsigned short *)obj_start; - ASSERT_TAG(tag); - fixup_table[tag](obj_start, gc); - } - break; - case PAGE_ATOMIC: - break; - case PAGE_PAIR: - { - Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); - gcFIXUP2(SCHEME_CAR(p), gc); - gcFIXUP2(SCHEME_CDR(p), gc); - } - break; - default: - printf("Unhandled info->type %i\n", info->type); - abort(); + switch(info->type) { + case PAGE_ARRAY: + { + void **tempend = PPTR(info) + info->size, **tmpstart; + tmpstart = OBJHEAD_TO_OBJPTR(start); + while (tmpstart < tempend) gcFIXUP2(*tmpstart++, gc); } + break; + case PAGE_TAGGED: + { + void *obj_start = OBJHEAD_TO_OBJPTR(start); + unsigned short tag = *(unsigned short *)obj_start; + ASSERT_TAG(tag); + fixup_table[tag](obj_start, gc); + } + break; + case PAGE_ATOMIC: + break; + case PAGE_PAIR: + { + Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); + gcFIXUP2(SCHEME_CAR(p), gc); + gcFIXUP2(SCHEME_CDR(p), gc); + } + break; + default: + printf("Unhandled info->type %i\n", info->type); + abort(); } } start += info->size; } - - return non_dead; } static void repair_heap(NewGC *gc) -/* not dead => fixup pointers */ +/* Set `dead` bit if not `mark`, otherwise clean `mark`. After this + pass, objects are live if `dead` is not set. + Then, not dead => fixup pointers. */ { uintptr_t memory_in_use; mpage *page, *next; Fixup2_Proc *fixup_table = gc->fixup_table; - int need_fixup; + int need_fixup, minor_for_incremental; /* These pages are guaranteed not to be protected, because they've been marked on or marked from. @@ -4598,12 +4903,11 @@ static void repair_heap(NewGC *gc) page = gc->modified_next; gc->modified_next = NULL; - gc->reprotect_next = NULL; - memory_in_use = gc->memory_in_use; need_fixup = gc->need_fixup; - + minor_for_incremental = !gc->gc_full && gc->mark_gen1; + for (; page; page = next) { GC_ASSERT(page->marked_on || page->marked_from); next = page->modified_next; @@ -4613,17 +4917,27 @@ static void repair_heap(NewGC *gc) page->has_new = 0; if (gc->gc_full) page->marked_on = 1; - else + else { + if (gc->mark_gen1 && page->marked_on) + page_marked_on(gc, page, 0, 1); page->marked_on = 0; + } page->marked_from = 0; gc->back_pointers = 0; if (page->size_class >= SIZE_CLASS_BIG_PAGE) { - void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); - void **end = PAGE_END_VSS(page); + /* ------ big page ------ */ + if (minor_for_incremental) { + /* leave mark */ + } else + page->size_class = SIZE_CLASS_BIG_PAGE; /* remove the mark, if any */ - GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", - page, start)); if (need_fixup) { + void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); + void **end = PAGE_END_VSS(page); + + GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", + page, start)); + switch(page->page_type) { case PAGE_TAGGED: fixup_table[*(unsigned short*)start](start, gc); @@ -4644,17 +4958,54 @@ static void repair_heap(NewGC *gc) memory_in_use += page->size; } else if (page->size_class == SIZE_CLASS_SMALL_PAGE) { + int need_unmark = 0; + /* ------ small page ------ */ + if (minor_for_incremental) { + /* leave marks as-is */ + } else { + int live_size; + GCDEBUG((DEBUGOUTF, "Unmarking objs on page %p, starting with %p\n", + page, start)); + /* Although it's more complicated, it's worth fusing the unmark + and operations passes to avoid traversing the page twice. */ + if (!need_fixup + || (page->page_type == PAGE_ATOMIC) + || (page->scan_boundary != PREFIX_SIZE)) { + live_size = unmark_range(PPTR(NUM(page->addr) + page->scan_boundary), + PAGE_END_VSS(page)); + + if (page->scan_boundary == PREFIX_SIZE) + page->live_size = live_size; + } else + need_unmark = 1; + } + if (need_fixup) { - void **start = PPTR(NUM(page->addr) + page->scan_boundary); + /* fixup should walk the full page: */ + void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); void **end = PAGE_END_VSS(page); + int live_size = 0; GCDEBUG((DEBUGOUTF, "Cleaning objs on page %p, starting with %p\n", page, start)); switch(page->page_type) { - case PAGE_TAGGED: + case PAGE_TAGGED: while(start < end) { objhead *info = (objhead *)start; + int fixup; - if(!info->dead) { + if (need_unmark) { + if (info->mark) { + info->mark = 0; + live_size += info->size; + fixup = 1; + } else { + info->dead = 1; + fixup = 0; + } + } else + fixup = !info->dead; + + if (fixup) { void *obj_start = OBJHEAD_TO_OBJPTR(start); unsigned short tag = *(unsigned short *)obj_start; ASSERT_TAG(tag); @@ -4669,7 +5020,21 @@ static void repair_heap(NewGC *gc) while(start < end) { objhead *info = (objhead *)start; size_t size = info->size; - if(!info->dead) { + int fixup; + + if (need_unmark) { + if (info->mark) { + info->mark = 0; + live_size += size; + fixup = 1; + } else { + info->dead = 1; + fixup = 0; + } + } else + fixup = !info->dead; + + if (fixup) { void **tempend = PPTR(info) + info->size; start = OBJHEAD_TO_OBJPTR(start); while(start < tempend) gcFIXUP2(*start++, gc); @@ -4681,7 +5046,21 @@ static void repair_heap(NewGC *gc) case PAGE_PAIR: while(start < end) { objhead *info = (objhead *)start; - if(!info->dead) { + int fixup; + + if (need_unmark) { + if (info->mark) { + info->mark = 0; + live_size += (PAIR_SIZE_IN_BYTES >> LOG_WORD_SIZE); + fixup = 1; + } else { + info->dead = 1; + fixup = 0; + } + } else + fixup = !info->dead; + + if (fixup) { Scheme_Object *p = (Scheme_Object *)OBJHEAD_TO_OBJPTR(start); gcFIXUP2(SCHEME_CAR(p), gc); gcFIXUP2(SCHEME_CDR(p), gc); @@ -4690,21 +5069,51 @@ static void repair_heap(NewGC *gc) } break; } + + if (page->page_type != PAGE_ATOMIC) + page->live_size = live_size; } + /* everything on this page is now old-generation: */ page->scan_boundary = page->size; + memory_in_use += page->size; } else { - int non_dead; + /* ------ medium page ------ */ GC_ASSERT(page->size_class == SIZE_CLASS_MED_PAGE); - non_dead = repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size), need_fixup); - page->live_size = (page->obj_size * non_dead); + + if (minor_for_incremental) { + if (page->generation == AGE_GEN_0) { + /* Don't clear `mark` flags, but do set `dead` flags, + so that the page will be treated correctly by + mark_backpointers. */ + void **start = PPTR(NUM(page->addr) + PREFIX_SIZE); + void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size); + while(start < end) { + objhead *info = (objhead *)start; + if (!info->mark) + info->dead = 1; + start += info->size; + } + } + } else { + if ((page->generation == AGE_GEN_0) || gc->gc_full) { + int live_size; + live_size = unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), + PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); + page->live_size = live_size; + } + } + + if (need_fixup) + repair_mixed_page(gc, page, PPTR(NUM(page->addr) + APAGE_SIZE - page->obj_size)); + memory_in_use += page->live_size; page->med_search_start = PREFIX_SIZE; /* start next block search at the beginning */ if (page->generation == AGE_GEN_0) { /* Tell the clean-up phase to keep this one (needed even for a minor GC): */ page->marked_on = 1; - GC_ASSERT(non_dead); /* otherwise, wouldn't have marked_on */ + GC_ASSERT(page->live_size); /* otherwise, wouldn't have marked_on */ } } @@ -4716,21 +5125,81 @@ static void repair_heap(NewGC *gc) page->back_pointers = 0; if ((page->page_type != PAGE_ATOMIC) && (page->page_type != PAGE_MED_ATOMIC)) { - page->reprotect_next = gc->reprotect_next; - gc->reprotect_next = page; + if (page->reprotect) { + /* must have been set for incremental, but also used for new gen1 objects + moved from gen0 */ + GC_ASSERT(!gc->gc_full); + GC_ASSERT(gc->mark_gen1); + } else { + page->reprotect_next = gc->reprotect_next; + gc->reprotect_next = page; + } } } } /* All gen-half pages count as modified: */ - for (page = gc->gen_half.pages; page; page = page->next) { - GC_ASSERT(page->generation == AGE_GEN_HALF); - (void)repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1), need_fixup); + if (need_fixup) { + for (page = gc->gen_half.pages; page; page = page->next) { + GC_ASSERT(page->generation == AGE_GEN_HALF); + unmark_range(PPTR(NUM(page->addr) + PREFIX_SIZE), + PPTR(NUM(page->addr) + page->size - 1)); + repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1)); + } } memory_in_use += gen_half_size_in_use(gc); memory_in_use = add_no_overflow(memory_in_use, gc->phantom_count); gc->memory_in_use = memory_in_use; + + + +#if CHECK_NO_MISSED_FIXUPS + /* Double-check that no fixups apply to live objects at this point */ + if (need_fixup) { + int i; + + disallow_fixups++; + + for (i = 0; i < PAGE_BIG; i++) { + if (i != PAGE_ATOMIC) { + for (page = gc->gen1_pages[i]; page; page = page->next) { + if ((page->generation != AGE_VACATED) + && (page->marked_on || page->inc_marked_on)) + repair_mixed_page(gc, page, PAGE_END_VSS(page)-1); + } + } + } + + for (page = gc->gen1_pages[PAGE_BIG]; page; page = page->next) { + if (page->marked_on || page->inc_marked_on) { + void **start = PPTR(BIG_PAGE_TO_OBJECT(page)); + void **end = PAGE_END_VSS(page); + switch(page->page_type) { + case PAGE_TAGGED: + fixup_table[*(unsigned short*)start](start, gc); + break; + case PAGE_ATOMIC: break; + case PAGE_ARRAY: + while(start < end) gcFIXUP2(*(start++), gc); + break; + case PAGE_PAIR: + GC_ASSERT(0); + break; + } + } + } + + for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { + for (page = gc->med_pages[MED_PAGE_NONATOMIC_INDEX][i]; page; page = page->next) { + if (page->marked_on || page->inc_marked_on) + repair_mixed_page(gc, page, PPTR(NUM(page->addr) + page->size - 1)); + } + } + + --disallow_fixups; + } +#endif } static inline void cleanup_vacated_pages(NewGC *gc) { @@ -4941,6 +5410,7 @@ static void protect_old_pages(NewGC *gc) GC_ASSERT(page->page_type != PAGE_ATOMIC); GC_ASSERT(page->page_type != PAGE_MED_ATOMIC); GC_ASSERT(page->generation != AGE_VACATED); + page->reprotect = 0; if (!page->back_pointers) { page->mprotected = 1; mmu_queue_write_protect_range(mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); @@ -4955,9 +5425,51 @@ static void protect_old_pages(NewGC *gc) } } + gc->reprotect_next = NULL; + mmu_flush_write_protect_ranges(mmu); } +#if 0 +static void check_marks_cleared_range(void **start, void **end) +{ + while(start < end) { + objhead *info = (objhead *)start; + + GC_ASSERT(!info->mark); + + start += info->size; + } +} + +static void check_marks_cleared(NewGC *gc) +{ + mpage *page; + int i, ty; + + for (i = 0; i < PAGE_BIG; i++) { + for (page = gc->gen1_pages[i]; page; page = page->next) { + GC_ASSERT(page->size == page->scan_boundary); + check_marks_cleared_range(PAGE_START_VSS(page), PAGE_END_VSS(page)); + } + } + + for (page = gc->gen1_pages[PAGE_BIG]; page; page = page->next) { + GC_ASSERT(page->size_class == SIZE_CLASS_BIG_PAGE); + } + + for (ty = 0; ty < MED_PAGE_TYPES; ty++) { + for (i = 0; i < NUM_MED_PAGE_SIZES; i++) { + for (page = gc->med_pages[ty][i]; page; page = page->next) { + check_marks_cleared_range(PAGE_START_VSS(page), PAGE_END_VSS(page)); + } + } + } +} +#else +static void check_marks_cleared(NewGC *gc) { } +#endif + static void park_for_inform_callback(NewGC *gc) { /* Avoid nested collections, which would need @@ -4983,11 +5495,12 @@ static void unpark_for_inform_callback(NewGC *gc) #if 0 extern double scheme_get_inexact_milliseconds(void); +# define SHOW_TIME_NOW gc->gc_full # define TIME_DECLS() double start, task_start -# define TIME_INIT() start = task_start = scheme_get_inexact_milliseconds(); fprintf(stderr, "GC (%d):\n", gc->gc_full) -# define TIME_STEP(task) fprintf(stderr, " %s: %lf\n", task, scheme_get_inexact_milliseconds() - task_start); \ +# define TIME_INIT() start = task_start = scheme_get_inexact_milliseconds(); if (SHOW_TIME_NOW) fprintf(stderr, "GC (%d):\n", gc->gc_full) +# define TIME_STEP(task) if (SHOW_TIME_NOW) fprintf(stderr, " %s: %lf\n", task, scheme_get_inexact_milliseconds() - task_start); \ task_start = scheme_get_inexact_milliseconds() -# define TIME_DONE() fprintf(stderr, " Total: %lf\n", scheme_get_inexact_milliseconds() - start) +# define TIME_DONE() if (SHOW_TIME_NOW) fprintf(stderr, " Total: %lf\n", scheme_get_inexact_milliseconds() - start) #else # define TIME_DECLS() /**/ # define TIME_INIT() /**/ @@ -5005,8 +5518,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin uintptr_t old_mem_use; uintptr_t old_gen0; uintptr_t old_mem_allocated; - int next_gc_full; + int do_incremental = 0; old_mem_use = gc->memory_in_use; /* includes gc->phantom_count */ old_gen0 = gc->gen0.current_size + gc->gen0_phantom_count; @@ -5017,20 +5530,33 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin dump_page_map(gc, "pre"); /* determine if this should be a full collection or not */ - gc->gc_full = force_full || !gc->generations_available - || (gc->since_last_full > FORCE_MAJOR_AFTER_COUNT) || (gc->memory_in_use > (2 * gc->last_full_mem_use)); -#if 0 - printf("Collection %li (full = %i): %i / %i / %i / %i %ld\n", number_of_gc_runs, - gc->gc_full, force_full, !generations_available, - (gc->since_last_full > FORCE_MAJOR_AFTER_COUNT), (gc->memory_in_use > (2 * gc->last_full_mem_use)), - gc->last_full_mem_use); -#endif + gc->gc_full = (force_full + || !gc->generations_available + /* Force a full GC when current memory use has grown + to a given ratio of memory use after the last GC. + This approach makes total memory use roughly a constant + fraction of the actual use by live data: */ + || (gc->memory_in_use > (FULL_COLLECTION_SIZE_RATIO * gc->last_full_mem_use)) + /* Just in case, for a full GC every so often, unless + incremental mode has been enabled: */ + || ((gc->since_last_full > FORCE_MAJOR_AFTER_COUNT) + && !gc->started_incremental) + /* In incremental mode, maybe GC earlier. Since incremental + mode promotes objects from gen0 to already-marked + old-generation objects, we try to keep memory use at + some limit from before incremental mode started. At + the same time, we don't want to start if there's still + worked queued to perform incrementally. */ + || (gc->started_incremental + && (gc->memory_in_use > gc->inc_mem_use_threshold) + && (!gc->inc_mark_stack + || (gc->inc_mark_stack->top == MARK_STACK_START(gc->inc_mark_stack))))); if (gc->gc_full && no_full) { return; } - next_gc_full = gc->gc_full; + next_gc_full = gc->gc_full && !gc->started_incremental; if (gc->full_needed_for_finalization) { gc->full_needed_for_finalization= 0; @@ -5044,6 +5570,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->number_of_gc_runs++; INIT_DEBUG_FILE(); DUMP_HEAP(); + gc->prop_count = 0; + /* we don't want the low-level allocator freaking because we've gone past half the available memory */ gc->in_unsafe_allocation_mode = 1; @@ -5061,6 +5589,19 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->need_fixup = 0; + do_incremental = (!gc->gc_full && (gc->incremental_requested + || ALWAYS_COLLECT_INCREMENTAL_ON_MINOR)); + if (!postmaster_and_place_gc(gc)) + do_incremental = 0; + + if (do_incremental) + gc->started_incremental = 1; + + gc->incremental_requested = 0; + + gc->mark_gen1 = gc->gc_full || gc->started_incremental; + gc->check_gen1 = gc->gc_full; + TIME_INIT(); /* inform the system (if it wants us to) that we're starting collection */ @@ -5072,7 +5613,12 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->no_further_modifications = 1; if (gc->gc_full) - reset_gen1_pages_live_and_scan_boundaries(gc); + merge_incremental_mark_stack(gc); + else if (gc->mark_gen1) + incremental_mark_stack_initialize(gc); + + if (gc->gc_full) + reset_gen1_pages_scan_boundaries(gc); if (gc->gc_full) merge_finalizer_trees(gc); @@ -5146,6 +5692,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin zero_weak_arrays(gc, 1); zero_remaining_ephemerons(gc); + if (do_incremental) + propagate_incremental_marks(gc, INCREMENTAL_COLLECT_FUEL); + TIME_STEP("finalized2"); #if MZ_GC_BACKTRACE @@ -5175,7 +5724,6 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin chain_marked_on(gc); else if (gc->gc_full) chain_marked_on_check(gc); - unmark_heap(gc); repair_heap(gc); TIME_STEP("repaired"); clean_up_heap(gc); @@ -5207,6 +5755,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin mmu_flush_freed_pages(gc->mmu); reset_finalizer_tree(gc); + if (gc->gc_full || !gc->started_incremental) + check_marks_cleared(gc); + TIME_STEP("reset"); /* now we do want the allocator freaking if we go over half */ @@ -5214,6 +5765,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin gc->no_further_modifications = 0; + if (gc->gc_full) + free_incremental_admin_pages(gc); + check_excessive_free_pages(gc); /* update some statistics */ @@ -5231,8 +5785,16 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin else gc->since_last_full += 10; } - if(gc->gc_full) + if (gc->gc_full) { gc->last_full_mem_use = gc->memory_in_use; + if (!gc->started_incremental + || ((FULL_COLLECTION_SIZE_RATIO * gc->memory_in_use) < gc->inc_mem_use_threshold) + || (gc->memory_in_use > gc->inc_mem_use_threshold)) + gc->inc_mem_use_threshold = (FULL_COLLECTION_SIZE_RATIO * gc->memory_in_use); + + gc->started_incremental = 0; + gc->inc_prop_count = 0; + } /* inform the system (if it wants us to) that we're done with collection */ if (gc->GC_collect_end_callback) @@ -5447,6 +6009,7 @@ static void free_gc(NewGC *gc) free_page_maps(gc->page_maps); free_all_stack_pages(gc); + free_incremental_admin_pages(gc); mmu_flush_freed_pages(gc->mmu); mmu_free(gc->mmu); diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index a730aef9c9..1456f7603f 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -15,6 +15,7 @@ typedef struct mpage { void *addr; void *mmu_src_block; struct mpage *modified_next; /* next in chain of pages for backpointers, marks, etc. */ + struct mpage *inc_modified_next; /* like modified_next, but for incrementally marked pages */ struct mpage *reprotect_next; /* next in a chain of pages that need to be re-protected */ #ifdef MZ_GC_BACKTRACE void **backtrace; @@ -44,9 +45,11 @@ typedef struct mpage { unsigned char size_class :2; unsigned char page_type :3; unsigned char marked_on :1; + unsigned char inc_marked_on :1; unsigned char marked_from :1; unsigned char has_new :1; unsigned char mprotected :1; + unsigned char reprotect :1; /* in reprotect_next chain already */ } mpage; typedef struct Gen0 { @@ -82,6 +85,11 @@ typedef struct MarkSegment { void **top; } MarkSegment; +typedef struct Inc_Admin_Page { + struct Inc_Admin_Page *next; + size_t size, pos; +} Inc_Admin_Page; + typedef struct GC_Thread_Info { void *thread; int owner; @@ -158,11 +166,13 @@ typedef struct NewGC { /* linked list of pages with back pointers to be traversed in a minor collection, etc.: */ struct mpage *modified_next; + /* pages marked incrementally: */ + struct mpage *inc_modified_next; /* linked list of pages that need to be given write protection at the end of the GC cycle: */ struct mpage *reprotect_next; - MarkSegment *mark_stack; + MarkSegment *mark_stack, *inc_mark_stack; /* Finalization */ Fnl *run_queue; @@ -189,6 +199,7 @@ typedef struct NewGC { int avoid_collection; unsigned char generations_available :1; + unsigned char started_incremental :1; /* must stick with incremental until major GC */ unsigned char in_unsafe_allocation_mode :1; unsigned char full_needed_for_finalization :1; unsigned char no_further_modifications :1; @@ -197,6 +208,11 @@ typedef struct NewGC { unsigned char running_finalizers :1; unsigned char back_pointers :1; unsigned char need_fixup :1; + unsigned char check_gen1 :1; + unsigned char mark_gen1 :1; + unsigned char inc_gen1 :1; + unsigned char during_backpointer :1; + unsigned char incremental_requested :1; /* blame the child */ unsigned int doing_memory_accounting :1; @@ -215,6 +231,10 @@ typedef struct NewGC { uintptr_t number_of_gc_runs; unsigned int since_last_full; uintptr_t last_full_mem_use; + uintptr_t inc_mem_use_threshold; + + uintptr_t prop_count; + uintptr_t inc_prop_count; /* These collect information about memory usage, for use in GC_dump. */ uintptr_t peak_memory_use; @@ -227,7 +247,6 @@ typedef struct NewGC { uintptr_t modified_unprotects; /* THREAD_LOCAL variables that need to be saved off */ - MarkSegment *saved_mark_stack; void *saved_GC_variable_stack; uintptr_t saved_GC_gen0_alloc_page_ptr; uintptr_t saved_GC_gen0_alloc_page_end; @@ -238,7 +257,9 @@ typedef struct NewGC { int dont_master_gc_until_child_registers; /* :1: */ #endif - struct mpage *thread_local_pages; + Inc_Admin_Page *inc_space; + + struct mpage *thread_local_pages; /* Callbacks */ void (*GC_collect_start_callback)(void); @@ -268,13 +289,23 @@ typedef struct NewGC { uintptr_t phantom_count; uintptr_t gen0_phantom_count; - Roots roots; - GC_Weak_Array *weak_arrays; - GC_Weak_Box *weak_boxes[2]; - GC_Ephemeron *ephemerons; - int num_last_seen_ephemerons; + Roots roots; struct MMU *mmu; + /* The `inc_` variants hold old-generation objects discovered in + incremental mode. If incremental mode is started, the plain + variants for a minor collection need to be added to the `inc_` + variants, since promoted objects from the nursery keep their mark + bits. The `bp_` variants are old-generation objects that were + marked as (potentially) containing backpointers; they are treated + like the normal ones, but not added to `inc_` because they're + either already marked or should be added when they're later + marked. */ + GC_Weak_Array *weak_arrays, *inc_weak_arrays, *bp_weak_arrays; + GC_Weak_Box *weak_boxes[2], *inc_weak_boxes[2], *bp_weak_boxes[2]; + GC_Ephemeron *ephemerons, *inc_ephemerons, *bp_ephemerons; + int num_last_seen_ephemerons; + Allocator *saved_allocator; #ifdef MZ_USE_PLACES diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index 3964715b4a..7e4596a999 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -17,6 +17,7 @@ weak_box_tag ephemeron_tag is_marked(p) + is_in_generation_half(p) Type_Tag */ @@ -30,7 +31,7 @@ static int size_weak_array(void *p, struct NewGC *gc) GC_Weak_Array *a = (GC_Weak_Array *)p; return gcBYTES_TO_WORDS(sizeof(GC_Weak_Array) - + ((a->count - 1) * sizeof(void *))); + + ((a->count - 1 + 1) * sizeof(void *))); } static int mark_weak_array(void *p, struct NewGC *gc) @@ -39,8 +40,24 @@ static int mark_weak_array(void *p, struct NewGC *gc) gcMARK2(a->replace_val, gc); - a->next = gc->weak_arrays; - gc->weak_arrays = a; + if (gc->doing_memory_accounting) { + /* skip */ + } else if (gc->inc_gen1) { + /* inc_next field is at the end of the `data` array: */ + a->data[a->count] = gc->inc_weak_arrays; + gc->inc_weak_arrays = a; + } else if (gc->during_backpointer) { + if (!gc->gc_full) { + /* Keep backpointered weak arrays separate, because we + should not merge them to the incremental list + in incremental mode. */ + a->next = gc->bp_weak_arrays; + gc->bp_weak_arrays = a; + } + } else { + a->next = gc->weak_arrays; + gc->weak_arrays = a; + } #if CHECKS /* For now, weak arrays only used for symbols, keywords, and falses: */ @@ -60,7 +77,7 @@ static int mark_weak_array(void *p, struct NewGC *gc) #endif return gcBYTES_TO_WORDS(sizeof(GC_Weak_Array) - + ((a->count - 1) * sizeof(void *))); + + ((a->count - 1 + 1) * sizeof(void *))); } static int fixup_weak_array(void *p, struct NewGC *gc) @@ -93,7 +110,8 @@ void *GC_malloc_weak_array(size_t size_in_bytes, void *replace_val) w = (GC_Weak_Array *)GC_malloc_one_tagged(size_in_bytes + sizeof(GC_Weak_Array) - - sizeof(void *)); + - sizeof(void *) + + sizeof(GC_Weak_Array *)); replace_val = gc->park[0]; gc->park[0] = NULL; @@ -105,16 +123,52 @@ void *GC_malloc_weak_array(size_t size_in_bytes, void *replace_val) return w; } +static void rechain_inc_weak_arrays(GC_Weak_Array *w) +{ + for (; w; w = (GC_Weak_Array *)w->data[w->count]) { + w->next = (GC_Weak_Array *)w->data[w->count]; + } +} + static void init_weak_arrays(GCTYPE *gc) { - gc->weak_arrays = NULL; + if (gc->gc_full) { + rechain_inc_weak_arrays(gc->inc_weak_arrays); + gc->weak_arrays = gc->inc_weak_arrays; + gc->inc_weak_arrays = NULL; + } else + gc->weak_arrays = NULL; + gc->bp_weak_arrays = NULL; +} + +static GC_Weak_Array *append_weak_arrays(GC_Weak_Array *wa, GC_Weak_Array *bp_wa, int *_num_gen0) +{ + *_num_gen0 = 0; + + if (wa) { + GC_Weak_Array *last_wa = wa; + while (last_wa->next) { + (*_num_gen0)++; + last_wa = last_wa->next; + } + (*_num_gen0)++; + last_wa->next = bp_wa; + return wa; + } else + return bp_wa; } static void zero_weak_arrays(GCTYPE *gc, int force_zero) { GC_Weak_Array *wa; - int i; + int i, num_gen0; + + GC_ASSERT(!gc->bp_weak_arrays || !gc->gc_full); + + wa = append_weak_arrays(gc->weak_arrays, gc->bp_weak_arrays, &num_gen0); + + if (gc->gc_full || !gc->started_incremental) + num_gen0 = 0; - wa = gc->weak_arrays; while (wa) { void **data; @@ -127,16 +181,47 @@ static void zero_weak_arrays(GCTYPE *gc, int force_zero) data[i] = GC_resolve2(p, gc); } + if (num_gen0 > 0) { + if (!is_in_generation_half(gc, wa)) { + /* For incremental mode, preserve this weak box + in the incremental list for re-checking later. */ + wa->data[wa->count] = gc->inc_weak_arrays; + gc->inc_weak_arrays = wa; + } + } + wa = wa->next; + num_gen0--; } gc->weak_arrays = NULL; + gc->bp_weak_arrays = NULL; } /******************************************************************************/ /* weak boxes */ /******************************************************************************/ +#if 0 +static void check_weak_box_not_already_in_inc_chain(GC_Weak_Box *wb, GC_Weak_Box *wbc) +{ + while (wbc) { + GC_ASSERT(wb != wbc); + wbc = wbc->inc_next; + } +} +static void check_weak_box_not_already_in_chain(GC_Weak_Box *wb, GC_Weak_Box *wbc) +{ + while (wbc) { + GC_ASSERT(wb != wbc); + wbc = wbc->next; + } +} +#else +static void check_weak_box_not_already_in_inc_chain(GC_Weak_Box *wb, GC_Weak_Box *wbc) { } +static void check_weak_box_not_already_in_chain(GC_Weak_Box *wb, GC_Weak_Box *wbc) { } +#endif + static int size_weak_box(void *p, struct NewGC *gc) { return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box)); @@ -145,10 +230,28 @@ static int size_weak_box(void *p, struct NewGC *gc) static int mark_weak_box(void *p, struct NewGC *gc) { GC_Weak_Box *wb = (GC_Weak_Box *)p; - + gcMARK2(wb->secondary_erase, gc); - if (wb->val) { + if (gc->doing_memory_accounting) { + /* skip */ + } else if (gc->inc_gen1) { + check_weak_box_not_already_in_inc_chain(wb, gc->inc_weak_boxes[wb->is_late]); + wb->inc_next = gc->inc_weak_boxes[wb->is_late]; + gc->inc_weak_boxes[wb->is_late] = wb; + } else if (gc->during_backpointer) { + if (!gc->gc_full && (wb->val || gc->started_incremental)) { + /* Keep backpointered weak arrays separate, because we + should not merge them to the incremental list + in incremental mode. */ + check_weak_box_not_already_in_chain(wb, gc->bp_weak_boxes[wb->is_late]); + check_weak_box_not_already_in_chain(wb, gc->weak_boxes[wb->is_late]); + wb->next = gc->bp_weak_boxes[wb->is_late]; + gc->bp_weak_boxes[wb->is_late] = wb; + } + } else if (wb->val || gc->started_incremental) { + check_weak_box_not_already_in_chain(wb, gc->weak_boxes[wb->is_late]); + check_weak_box_not_already_in_chain(wb, gc->bp_weak_boxes[wb->is_late]); wb->next = gc->weak_boxes[wb->is_late]; gc->weak_boxes[wb->is_late] = wb; } @@ -195,18 +298,64 @@ void *GC_malloc_weak_box(void *p, void **secondary, int soffset, int is_late) return w; } +static void rechain_inc_weak_boxes(GC_Weak_Box *wb) +{ + for (; wb; wb = wb->inc_next) { + wb->next = wb->inc_next; + } +} + static void init_weak_boxes(GCTYPE *gc) { - gc->weak_boxes[0] = NULL; - gc->weak_boxes[1] = NULL; + if (gc->gc_full) { + rechain_inc_weak_boxes(gc->inc_weak_boxes[0]); + rechain_inc_weak_boxes(gc->inc_weak_boxes[1]); + gc->weak_boxes[0] = gc->inc_weak_boxes[0]; + gc->weak_boxes[1] = gc->inc_weak_boxes[1]; + gc->inc_weak_boxes[0] = NULL; + gc->inc_weak_boxes[1] = NULL; + } else { + gc->weak_boxes[0] = NULL; + gc->weak_boxes[1] = NULL; + } + gc->bp_weak_boxes[0] = NULL; + gc->bp_weak_boxes[1] = NULL; +} + +static GC_Weak_Box *append_weak_boxes(GC_Weak_Box *wb, GC_Weak_Box *bp_wb, int *_num_gen0) +{ + *_num_gen0 = 0; + + if (wb) { + GC_Weak_Box *last_wb = wb; + while (last_wb->next) { + (*_num_gen0)++; + last_wb = last_wb->next; + } + (*_num_gen0)++; + last_wb->next = bp_wb; + return wb; + } else + return bp_wb; } static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) { GC_Weak_Box *wb; + int num_gen0; + + GC_ASSERT(!gc->bp_weak_boxes[is_late] || !gc->gc_full); + + wb = append_weak_boxes(gc->weak_boxes[is_late], + gc->bp_weak_boxes[is_late], + &num_gen0); + if (gc->gc_full || !gc->started_incremental) + num_gen0 = 0; - wb = gc->weak_boxes[is_late]; while (wb) { - if (force_zero || !is_marked(gc, wb->val)) { + GC_ASSERT(is_marked(gc, wb)); + if (!wb->val) { + /* nothing to do */ + } else if (force_zero || !is_marked(gc, wb->val)) { wb->val = NULL; if (wb->secondary_erase) { void **p; @@ -219,18 +368,28 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) page->mprotected = 0; mmu_write_unprotect_page(gc->mmu, page->addr, APAGE_SIZE, page_mmu_type(page), &page->mmu_src_block); } - p = (void **)GC_resolve2(wb->secondary_erase, gc); *(p + wb->soffset) = NULL; wb->secondary_erase = NULL; } - } else + } else { wb->val = GC_resolve2(wb->val, gc); + } + if (num_gen0 > 0) { + if (!is_in_generation_half(gc, wb)) { + /* For incremental mode, preserve this weak box + in the incremental list for re-checking later. */ + wb->inc_next = gc->inc_weak_boxes[is_late]; + gc->inc_weak_boxes[is_late] = wb; + } + } wb = wb->next; + num_gen0--; } /* reset, in case we have a second round */ gc->weak_boxes[is_late] = NULL; + gc->bp_weak_boxes[is_late] = NULL; } /******************************************************************************/ @@ -247,8 +406,19 @@ static int mark_ephemeron(void *p, struct NewGC *gc) GC_Ephemeron *eph = (GC_Ephemeron *)p; if (eph->val) { - eph->next = gc->ephemerons; - gc->ephemerons = eph; + GC_ASSERT(!gc->doing_memory_accounting); + if (gc->inc_gen1) { + eph->inc_next = gc->inc_ephemerons; + gc->inc_ephemerons = eph; + } else if (gc->during_backpointer) { + if (!gc->gc_full) { + eph->next = gc->bp_ephemerons; + gc->bp_ephemerons = eph; + } + } else { + eph->next = gc->ephemerons; + gc->ephemerons = eph; + } } return gcBYTES_TO_WORDS(sizeof(GC_Ephemeron)); @@ -305,31 +475,79 @@ void *GC_malloc_ephemeron(void *k, void *v) return eph; } +static void rechain_inc_ephemerons(GC_Ephemeron *e) +{ + for (; e; e = e->inc_next) { + e->next = e->inc_next; + } +} + void init_ephemerons(GCTYPE *gc) { - gc->ephemerons = NULL; + if (gc->gc_full) { + rechain_inc_ephemerons(gc->inc_ephemerons); + gc->ephemerons = gc->inc_ephemerons; + gc->inc_ephemerons = NULL; + } else + gc->ephemerons = NULL; + gc->bp_ephemerons = NULL; gc->num_last_seen_ephemerons = 0; } -static int mark_ready_ephemerons(GCTYPE *gc) +static int mark_ready_ephemerons(GCTYPE *gc, int inc_gen1) { - GC_Ephemeron *waiting = NULL, *next, *eph; - int did_one = 0; + GC_Ephemeron *waiting, *next, *eph; + int did_one = 0, j; GC_mark_no_recur(gc, 1); - for (eph = gc->ephemerons; eph; eph = next) { - next = eph->next; - if (is_marked(gc, eph->key)) { - eph->key = GC_resolve2(eph->key, gc); - gcMARK2(eph->val, gc); - gc->num_last_seen_ephemerons++; - did_one = 1; - } else { - eph->next = waiting; - waiting = eph; + for (j = 0; j < (inc_gen1 ? 1 : 2); j++) { + if (inc_gen1) + eph = gc->inc_ephemerons; + else if (j == 0) + eph = gc->ephemerons; + else + eph = gc->bp_ephemerons; + + waiting = NULL; + + for (; eph; eph = next) { + if (inc_gen1) + next = eph->inc_next; + else + next = eph->next; + if (is_marked(gc, eph->key)) { + if (!inc_gen1) + eph->key = GC_resolve2(eph->key, gc); + gcMARK2(eph->val, gc); + gc->num_last_seen_ephemerons++; + did_one = 1; + if (!inc_gen1 && (j == 0) && !gc->gc_full && gc->started_incremental) { + /* Need to preserve the ephemeron in the incremental list, + unless it's kept in generation 1/2 nistead of promoted to + generation 1. */ + if (!is_in_generation_half(gc, eph)) { + eph->inc_next = gc->inc_ephemerons; + gc->inc_ephemerons = eph; + } + } + } else { + if (inc_gen1) { + /* Ensure that we can write to the page containing the emphemeron: */ + check_incremental_unprotect(gc, pagemap_find_page(gc->page_maps, eph)); + eph->inc_next = waiting; + } else + eph->next = waiting; + waiting = eph; + } } + + if (inc_gen1) + gc->inc_ephemerons = waiting; + else if (j == 0) + gc->ephemerons = waiting; + else + gc->bp_ephemerons = waiting; } - gc->ephemerons = waiting; GC_mark_no_recur(gc, 0); diff --git a/racket/src/racket/include/schthread.h b/racket/src/racket/include/schthread.h index db10d94214..d7d35352cd 100644 --- a/racket/src/racket/include/schthread.h +++ b/racket/src/racket/include/schthread.h @@ -358,6 +358,7 @@ typedef struct Thread_Local_Variables { struct Scheme_Bucket_Table *scheme_module_code_cache_; struct Scheme_Object *group_member_cache_; struct Scheme_Prefix *scheme_prefix_finalize_; + struct Scheme_Prefix *scheme_inc_prefix_finalize_; struct Scheme_Hash_Table *loaded_extensions_; struct Scheme_Hash_Table *fullpath_loaded_extensions_; Scheme_Sleep_Proc scheme_place_sleep_; @@ -750,6 +751,7 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL; #define scheme_module_code_cache XOA (scheme_get_thread_local_variables()->scheme_module_code_cache_) #define group_member_cache XOA (scheme_get_thread_local_variables()->group_member_cache_) #define scheme_prefix_finalize XOA (scheme_get_thread_local_variables()->scheme_prefix_finalize_) +#define scheme_inc_prefix_finalize XOA (scheme_get_thread_local_variables()->scheme_inc_prefix_finalize_) #define loaded_extensions XOA (scheme_get_thread_local_variables()->loaded_extensions_) #define fullpath_loaded_extensions XOA (scheme_get_thread_local_variables()->fullpath_loaded_extensions_) #define scheme_place_sleep XOA (scheme_get_thread_local_variables()->scheme_place_sleep_) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index d8fcc1c5c6..49ec11910b 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -206,6 +206,7 @@ THREAD_LOCAL_DECL(int scheme_continuation_application_count); THREAD_LOCAL_DECL(static int generate_lifts_count); THREAD_LOCAL_DECL(int scheme_overflow_count); THREAD_LOCAL_DECL(Scheme_Prefix *scheme_prefix_finalize); +THREAD_LOCAL_DECL(Scheme_Prefix *scheme_inc_prefix_finalize); int scheme_get_overflow_count() { return scheme_overflow_count; } /* read-only globals */ @@ -411,6 +412,7 @@ void scheme_init_eval_places() { #ifdef MZ_PRECISE_GC scheme_prefix_finalize = (Scheme_Prefix *)0x1; /* 0x1 acts as a sentenel */ + scheme_inc_prefix_finalize = (Scheme_Prefix *)0x1; GC_set_post_propagate_hook(mark_pruned_prefixes); #endif #ifdef DEBUG_CHECK_STACK_FRAME_SIZE @@ -5965,7 +5967,7 @@ Scheme_Object **scheme_push_prefix(Scheme_Env *genv, Resolve_Prefix *rp, pf = scheme_malloc_tagged(sizeof(Scheme_Prefix) + ((i-mzFLEX_DELTA) * sizeof(Scheme_Object *)) + (tl_map_len * sizeof(int))); - pf->so.type = scheme_prefix_type; + pf->iso.so.type = scheme_prefix_type; pf->num_slots = i; pf->num_toplevels = rp->num_toplevels; pf->num_stxes = rp->num_stxes; @@ -6057,10 +6059,22 @@ Scheme_Object **scheme_resume_prefix(Scheme_Object *v) #ifdef MZ_PRECISE_GC static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC { + if (!GC_is_partial(gc)) { + if (scheme_inc_prefix_finalize != (Scheme_Prefix *)0x1) { + Scheme_Prefix *pf = scheme_inc_prefix_finalize; + while (pf->next_final != (Scheme_Prefix *)0x1) { + pf = pf->next_final; + } + pf->next_final = scheme_prefix_finalize; + scheme_prefix_finalize = scheme_inc_prefix_finalize; + scheme_inc_prefix_finalize = (Scheme_Prefix *)0x1; + } + } + if (scheme_prefix_finalize != (Scheme_Prefix *)0x1) { Scheme_Prefix *pf = scheme_prefix_finalize, *next; Scheme_Object *clo; - int i, *use_bits, maxpos; + int i, *use_bits, maxpos, inc_fixup_mode; scheme_prefix_finalize = (Scheme_Prefix *)0x1; while (pf != (Scheme_Prefix *)0x1) { @@ -6115,23 +6129,32 @@ static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC /* Fix up closures that reference this prefix: */ clo = (Scheme_Object *)GC_resolve2(pf->fixup_chain, gc); pf->fixup_chain = NULL; + inc_fixup_mode = SCHEME_PREFIX_FLAGS(pf) & 0x1; while (clo) { Scheme_Object *next; + if (inc_fixup_mode) { + next = ((Scheme_Object **)clo)[1]; + clo = ((Scheme_Object **)clo)[0]; + } if (SCHEME_TYPE(clo) == scheme_closure_type) { Scheme_Closure *cl = (Scheme_Closure *)clo; int closure_size = ((Scheme_Closure_Data *)GC_resolve2(cl->code, gc))->closure_size; - next = cl->vals[closure_size - 1]; + if (!inc_fixup_mode) + next = cl->vals[closure_size - 1]; cl->vals[closure_size-1] = (Scheme_Object *)pf; } else if (SCHEME_TYPE(clo) == scheme_native_closure_type) { Scheme_Native_Closure *cl = (Scheme_Native_Closure *)clo; int closure_size = ((Scheme_Native_Closure_Data *)GC_resolve2(cl->code, gc))->closure_size; - next = cl->vals[closure_size - 1]; + if (!inc_fixup_mode) + next = cl->vals[closure_size - 1]; cl->vals[closure_size-1] = (Scheme_Object *)pf; } else { - abort(); + MZ_ASSERT(0); } clo = (Scheme_Object *)GC_resolve2(next, gc); } + if (inc_fixup_mode) + SCHEME_PREFIX_FLAGS(pf) -= 0x1; /* Next */ next = pf->next_final; diff --git a/racket/src/racket/src/mzclpf_decl.inc b/racket/src/racket/src/mzclpf_decl.inc index 472b870ca8..a92bdf2378 100644 --- a/racket/src/racket/src/mzclpf_decl.inc +++ b/racket/src/racket/src/mzclpf_decl.inc @@ -1,2 +1,3 @@ /* setup for mzclpf_post.inc */ CLOSURE_DATA_TYPE *data; +int gc_mode; diff --git a/racket/src/racket/src/mzclpf_post.inc b/racket/src/racket/src/mzclpf_post.inc index 6d92d6eaac..2bfd7f7182 100644 --- a/racket/src/racket/src/mzclpf_post.inc +++ b/racket/src/racket/src/mzclpf_post.inc @@ -6,8 +6,11 @@ mark_pruned_prefixes() in "eval.c" --- NULLs out unused fields before finally marking the prefix. If the prefix is ever marked through some other reference, then - mark_pruned_prefixes() doesn't actually prune. */ - if (data) { + mark_pruned_prefixes() doesn't actually prune. + To support incremental collection, we rely on the fact that + and old-generation closure cannot point to a new-generation + prefix; the prefix is always allocated before the closure. */ + if (data && (gc_mode != GC_CURRENT_MODE_BACKPOINTER_REMARK)) { /* GLOBAL ASSUMPTION: prefix is at the end of a closure */ Scheme_Prefix *pf = (Scheme_Prefix *)c->vals[closure_size - 1]; @@ -24,8 +27,13 @@ /* We're the first to look at this prefix... */ /* Add it to the chain of prefixes to finish after all other marking: */ - pf->next_final = scheme_prefix_finalize; - scheme_prefix_finalize = pf; + if (gc_mode == GC_CURRENT_MODE_INCREMENTAL) { + pf->next_final = scheme_inc_prefix_finalize; + scheme_inc_prefix_finalize = pf; + } else { + pf->next_final = scheme_prefix_finalize; + scheme_prefix_finalize = pf; + } #ifdef MZ_GC_BACKTRACE pf->backpointer = (Scheme_Object *)c; #endif @@ -34,8 +42,19 @@ /* Add this closure to the chain to be repaired when the prefix is marked (and potentially moved): */ - c->vals[closure_size - 1] = pf->fixup_chain; - pf->fixup_chain = (Scheme_Object *)c; + if ((gc_mode == GC_CURRENT_MODE_INCREMENTAL) || (SCHEME_PREFIX_FLAGS(pf) & 0x1)) { + /* Can't steal closure slot for this purpose, since the + slot is still in use until a full collection finishes */ + Scheme_Object **pr; + pr = (Scheme_Object **)GC_malloc_for_incremental(2 * sizeof(Scheme_Object *)); + pr[0] = (Scheme_Object *)c; + pr[1] = (Scheme_Object *)pf->fixup_chain; + pf->fixup_chain = (Scheme_Object *)pr; + SCHEME_PREFIX_FLAGS(pf) |= 0x1; + } else { + c->vals[closure_size - 1] = pf->fixup_chain; + pf->fixup_chain = (Scheme_Object *)c; + } /* Mark just the elements of the prefix that are (newly) used: */ if ((uintptr_t)data->tl_map & 0x1) { diff --git a/racket/src/racket/src/mzclpf_pre.inc b/racket/src/racket/src/mzclpf_pre.inc index 3789513d45..bb48e47ebf 100644 --- a/racket/src/racket/src/mzclpf_pre.inc +++ b/racket/src/racket/src/mzclpf_pre.inc @@ -1,8 +1,18 @@ -/* setup for mzclpf_post.inc */ - if (!GC_is_partial(gc) && c->code) { + /* setup for mzclpf_post.inc */ + gc_mode = GC_current_mode(gc); + if ((gc_mode != GC_CURRENT_MODE_ACCOUNTING) + && c->code) { data = (CLOSURE_DATA_TYPE *)GC_resolve2(c->code, gc); if (data->tl_map) { - if (!GC_is_marked2(c->vals[closure_size - 1], gc)) { + /* In GC_CURRENT_MODE_BACKPOINTER_REMARK mode, we can + ignore the prefix, because it must be at least + as old as the closure. + In GC_CURRENT_MODE_MINOR, if the prefix is in an + old collection, then GC_is_marked() will return 1; + in incremental mode, we'll mark the prefix and + effectively disable unused-variable clearing. */ + if ((gc_mode == GC_CURRENT_MODE_BACKPOINTER_REMARK) + || !GC_is_marked2(c->vals[closure_size - 1], gc)) { /* don't mark last item, which is a prefix */ i--; } else diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index b575ee1979..073e4bc89d 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2473,7 +2473,7 @@ long_double scheme_long_double_expt(long_double x, long_double y); by any closure, when the prefix is accessed only by closures. */ typedef struct Scheme_Prefix { - Scheme_Object so; /* scheme_prefix_type */ + Scheme_Inclhash_Object iso; /* scheme_prefix_type; 0x1 => incremental-mode fixup chain */ int num_slots, num_toplevels, num_stxes; #ifdef MZ_PRECISE_GC struct Scheme_Prefix *next_final; /* for special GC handling */ @@ -2486,6 +2486,8 @@ typedef struct Scheme_Prefix /* followed by an array of `int's for tl_map uses */ } Scheme_Prefix; +#define SCHEME_PREFIX_FLAGS(obj) MZ_OPT_HASH_KEY(&(obj)->iso) + #define PREFIX_TO_USE_BITS(pf) \ (int *)((char *)pf + sizeof(Scheme_Prefix) + ((pf->num_slots - mzFLEX_DELTA) * sizeof(Scheme_Object *))) diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 6ff9efb9ef..f5551d1d19 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.3.0.1" +#define MZSCHEME_VERSION "6.3.0.2" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 1 +#define MZSCHEME_VERSION_W 2 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index c90024a925..8957fe383b 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -243,7 +243,7 @@ THREAD_LOCAL_DECL(struct Scheme_GC_Pre_Post_Callback_Desc *gc_prepost_callback_d ROSYM static Scheme_Object *read_symbol, *write_symbol, *execute_symbol, *delete_symbol, *exists_symbol; ROSYM static Scheme_Object *client_symbol, *server_symbol; -ROSYM static Scheme_Object *major_symbol, *minor_symbol; +ROSYM static Scheme_Object *major_symbol, *minor_symbol, *incremental_symbol; THREAD_LOCAL_DECL(static int do_atomic = 0); THREAD_LOCAL_DECL(static int missed_context_switch = 0); @@ -524,8 +524,10 @@ void scheme_init_thread(Scheme_Env *env) REGISTER_SO(major_symbol); REGISTER_SO(minor_symbol); + REGISTER_SO(incremental_symbol); major_symbol = scheme_intern_symbol("major"); minor_symbol = scheme_intern_symbol("minor"); + incremental_symbol = scheme_intern_symbol("incremental"); GLOBAL_PRIM_W_ARITY("dump-memory-stats" , scheme_dump_gc_stats, 0, -1, env); GLOBAL_PRIM_W_ARITY("vector-set-performance-stats!", current_stats , 1, 2, env); @@ -723,9 +725,13 @@ static Scheme_Object *collect_garbage(int argc, Scheme_Object *argv[]) scheme_collect_garbage_minor(); } else if ((argc < 1) || SAME_OBJ(major_symbol, argv[0])) { scheme_collect_garbage(); + } else if ((argc < 1) || SAME_OBJ(incremental_symbol, argv[0])) { +#ifdef MZ_PRECISE_GC + GC_request_incremental_mode(); +#endif } else { scheme_wrong_contract("collect-garbage", - "(or/c 'major 'minor)", + "(or/c 'major 'minor 'incremental)", 0, argc, argv); } From e803a3c15e457c13dca019b8d04263748a643b19 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 17 Oct 2015 07:00:37 -0600 Subject: [PATCH 332/381] unbreak no-places, no-futures build --- racket/src/racket/src/eval.c | 1 + racket/src/racket/src/schpriv.h | 1 + 2 files changed, 2 insertions(+) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 49ec11910b..e7aa77c07a 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -6150,6 +6150,7 @@ static void mark_pruned_prefixes(struct NewGC *gc) XFORM_SKIP_PROC cl->vals[closure_size-1] = (Scheme_Object *)pf; } else { MZ_ASSERT(0); + next = NULL; } clo = (Scheme_Object *)GC_resolve2(next, gc); } diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 073e4bc89d..a4a2fcd96f 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -183,6 +183,7 @@ THREAD_LOCAL_DECL(extern intptr_t scheme_total_gc_time); THREAD_LOCAL_DECL(extern int scheme_cont_capture_count); THREAD_LOCAL_DECL(extern int scheme_continuation_application_count); THREAD_LOCAL_DECL(extern struct Scheme_Prefix *scheme_prefix_finalize); +THREAD_LOCAL_DECL(extern struct Scheme_Prefix *scheme_inc_prefix_finalize); int scheme_num_types(void); From e957a7d6557f9718ba8493c20675b75a1145084a Mon Sep 17 00:00:00 2001 From: Juan Francisco Cantero Hurtado Date: Mon, 19 Oct 2015 14:53:47 +0200 Subject: [PATCH 333/381] Add config for linux/ppc64. --- racket/src/racket/sconfig.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/sconfig.h b/racket/src/racket/sconfig.h index f6e90bc29c..27fb376ea5 100644 --- a/racket/src/racket/sconfig.h +++ b/racket/src/racket/sconfig.h @@ -173,9 +173,16 @@ # define MZ_TRY_EXTFLONUMS # define ASM_DBLPREC_CONTROL_87 # endif -# if defined(__powerpc__) +# if defined(__powerpc__) && !defined(__powerpc64__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "ppc-"SPLS_LINUX # endif +# if defined(__powerpc64__) +# if defined(__LITTLE_ENDIAN__) +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "ppc64le-"SPLS_LINUX +# else +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "ppc64-"SPLS_LINUX +# endif +# endif # if defined(__mc68000__) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "m68k-"SPLS_LINUX # endif @@ -247,7 +254,7 @@ # define MZ_JIT_USE_MPROTECT # define MZ_USE_DWARF_LIBUNWIND #endif -#if defined(__powerpc__) +#if defined(__powerpc__) && !defined(__powerpc64__) # define MZ_USE_JIT_PPC #endif # if defined(__arm__) From 056ec806d5824a1cf8c195d1c00afc59c2a80afa Mon Sep 17 00:00:00 2001 From: Phil Nguyen Date: Wed, 14 Oct 2015 23:15:59 -0400 Subject: [PATCH 334/381] fix ranges of `set-union!`, `set-intersect!`, `dict-clear!` to be `void?` in doc --- pkgs/racket-doc/scribblings/reference/dicts.scrbl | 2 +- pkgs/racket-doc/scribblings/reference/sets.scrbl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/dicts.scrbl b/pkgs/racket-doc/scribblings/reference/dicts.scrbl index 121b58acad..97a7fb4103 100644 --- a/pkgs/racket-doc/scribblings/reference/dicts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/dicts.scrbl @@ -625,7 +625,7 @@ Supported for any @racket[dict] that supports @racket[dict-remove], } -@defproc[(dict-clear! [dict dict?]) dict?]{ +@defproc[(dict-clear! [dict dict?]) void?]{ Removes all of the key/value associations in @racket[dict]. diff --git a/pkgs/racket-doc/scribblings/reference/sets.scrbl b/pkgs/racket-doc/scribblings/reference/sets.scrbl index e26afa47c6..9500bfd8e8 100644 --- a/pkgs/racket-doc/scribblings/reference/sets.scrbl +++ b/pkgs/racket-doc/scribblings/reference/sets.scrbl @@ -449,7 +449,7 @@ Supported for any @racket[st] that @impl{implements} @racket[set-add] and @supp (set-union (set 1 2) (seteq 2 3)) (code:comment "Sets of different types cannot be unioned.") ]} -@defproc[(set-union! [st0 generic-set?] [st generic-set?] ...) generic-set?]{ +@defproc[(set-union! [st0 generic-set?] [st generic-set?] ...) void?]{ Adds the elements from all of the @racket[st]s to @racket[st0]. @@ -483,7 +483,7 @@ both @racket[set-clear] and @racket[set-add], and @supp{supports} @racket[set->s } -@defproc[(set-intersect! [st0 generic-set?] [st generic-set?] ...) generic-set?]{ +@defproc[(set-intersect! [st0 generic-set?] [st generic-set?] ...) void?]{ Removes every element from @racket[st0] that is not contained by all of the @racket[st]s. From 04e546716e6d504bc39ea8991ede71cf8e4d86c5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 19 Oct 2015 08:09:23 -0600 Subject: [PATCH 335/381] fix typo Thanks to Jack Firth. --- racket/src/racket/gc2/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/README b/racket/src/racket/gc2/README index f8cf64b87d..a6721bc617 100644 --- a/racket/src/racket/gc2/README +++ b/racket/src/racket/gc2/README @@ -81,7 +81,7 @@ reports whether an object at its old address has been marked; it works only on old addresses. Normally, the mark function for an object is called only when the -object is first marked in a given GC pass. When generational +object is first marked in a given GC pass. With generational collection, the mark function can be called for an old-generation object if it potentially changed since a previous collection; still, the mark function will be called only once during that collection, so From 8598d203faf018b3f4018b8d985c715f42a04c1d Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 13 Oct 2015 16:18:39 -0500 Subject: [PATCH 336/381] Add a missing property to an expression lifted by the contract system. Caused TR to miss it. --- racket/collects/racket/contract/base.rkt | 3 ++- racket/collects/racket/contract/private/base.rkt | 13 +++++++++++-- racket/collects/racket/contract/private/opt.rkt | 3 ++- racket/collects/racket/contract/private/provide.rkt | 9 ++------- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/racket/collects/racket/contract/base.rkt b/racket/collects/racket/contract/base.rkt index 857b341d67..d0d34b5ed1 100644 --- a/racket/collects/racket/contract/base.rkt +++ b/racket/collects/racket/contract/base.rkt @@ -43,7 +43,8 @@ "private/struct-dc.rkt" "private/struct-prop.rkt") (except-out (all-from-out "private/base.rkt") - current-contract-region) + current-contract-region + (for-syntax lifted-key add-lifted-property)) (except-out (all-from-out "private/misc.rkt") check-between/c check-unary-between/c diff --git a/racket/collects/racket/contract/private/base.rkt b/racket/collects/racket/contract/private/base.rkt index aee46da156..446bf538a6 100644 --- a/racket/collects/racket/contract/private/base.rkt +++ b/racket/collects/racket/contract/private/base.rkt @@ -3,7 +3,8 @@ (provide contract (rename-out [-recursive-contract recursive-contract]) current-contract-region - invariant-assertion) + invariant-assertion + (for-syntax lifted-key add-lifted-property)) (require (for-syntax racket/base syntax/name syntax/srcloc) racket/stxparam @@ -17,6 +18,13 @@ "generate.rkt" ) +(begin-for-syntax + (define lifted-key (gensym 'contract:lifted)) + ;; syntax? -> syntax? + ;; tells clients that the expression is a lifted application + (define (add-lifted-property stx) + (syntax-property stx lifted-key #t))) + (define-for-syntax lifted-ccrs (make-hasheq)) (define-syntax-parameter current-contract-region @@ -26,7 +34,8 @@ [id (hash-ref lifted-ccrs ctxt #f)]) (with-syntax ([id (or id (let ([id (syntax-local-lift-expression - (syntax/loc stx (quote-module-name)))]) + (add-lifted-property + (syntax/loc stx (quote-module-name))))]) (hash-set! lifted-ccrs ctxt (syntax-local-introduce id)) id))]) #'id)) diff --git a/racket/collects/racket/contract/private/opt.rkt b/racket/collects/racket/contract/private/opt.rkt index 2201eb1624..4743434a71 100644 --- a/racket/collects/racket/contract/private/opt.rkt +++ b/racket/collects/racket/contract/private/opt.rkt @@ -3,6 +3,7 @@ "misc.rkt" "blame.rkt" "guts.rkt" + "base.rkt" racket/stxparam) (require (for-syntax racket/base "helpers.rkt" @@ -273,7 +274,7 @@ (define-syntax (begin-lifted stx) (syntax-case stx () [(_ expr) - (syntax-local-lift-expression #'expr)])) + (syntax-local-lift-expression (add-lifted-property #'expr))])) (define-syntax (define-opt/c stx) (syntax-case stx () diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index d874ae1acd..9fd3edbe08 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -66,7 +66,6 @@ ;; keys for syntax property used below (define rename-id-key (gensym 'contract:rename-id)) - (define lifted-key (gensym 'contract:lifted)) (define neg-party-key (gensym 'contract:neg-party)) ;; identifier? identifier? -> identifier? @@ -74,11 +73,6 @@ (define (add-rename-id rename-id partial-id) (syntax-property partial-id rename-id-key rename-id)) - ;; syntax? -> syntax? - ;; tells clients that the expression is a lifted application - (define (add-lifted-property stx) - (syntax-property stx lifted-key #t)) - ;; identifier? -> identifier? ;; tells clients that the application of this id has an extra inserted argument (define (add-neg-party stx) @@ -119,7 +113,8 @@ ;; No: lift the neg name creation (syntax-local-introduce (syntax-local-lift-expression - #'(quote-module-name))))]) + (add-lifted-property + #'(quote-module-name)))))]) (when key (hash-set! global-saved-id-table key lifted-neg-party)) ;; Expand to a use of the lifted expression: (define (adjust-location new-stx) From d8733b4c52af53d5e67b6bcc8e7c26256f3f6057 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 19 Oct 2015 17:03:08 -0600 Subject: [PATCH 337/381] update racket/HISTORY.txt for v6.3 Merge to v6.3 --- racket/collects/racket/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/racket/collects/racket/HISTORY.txt b/racket/collects/racket/HISTORY.txt index 6365c90e78..8abe452910 100644 --- a/racket/collects/racket/HISTORY.txt +++ b/racket/collects/racket/HISTORY.txt @@ -1,3 +1,7 @@ +Version 6.3, October 2015 +Bug repairs and other changes noted in the documentation, + including substantial changes to the macro expander + Version 6.2, April 2015 Bug repairs and other changes noted in the documentation From 836316f5ed8f2edc8d07174776b866960e9858f0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 19 Oct 2015 17:08:35 -0600 Subject: [PATCH 338/381] fix `TEST_ALTERNATE_TARGET_REGISTER` build Merge to v6.3 --- racket/src/racket/src/jit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 181a21c1b0..a57816e51d 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -1916,7 +1916,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w return 1; } else if ((target == JIT_R1) && IS_SKIP_TYPE(SCHEME_TYPE(obj))) { - scheme_generate(obj, jitter, is_tail, wcm_may_replace, multi_ok, JIT_R0, for_branch); + scheme_generate(obj, jitter, is_tail, wcm_may_replace, multi_ok, JIT_R0, for_branch, NULL); CHECK_LIMIT(); jit_movr_p(JIT_R1, JIT_R0); return 1; From 079183eb6a16bbd41d01aaf2824e2ab8da3d6959 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 19 Oct 2015 17:24:34 -0600 Subject: [PATCH 339/381] fix cross-build for Windows to use `setup/winvers-change` Merge to v6.3 --- Makefile | 1 + racket/collects/setup/winvers-change.rkt | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 5c6d46272c..6feaba96e2 100644 --- a/Makefile +++ b/Makefile @@ -492,6 +492,7 @@ bundle-from-server: $(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(REQUIRED_PKGS) $(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(PKGS) $(RACKET) -l setup/unixstyle-install post-adjust "$(SOURCE_MODE)" "$(PKG_SOURCE_MODE)" racket bundle/racket + $(RACKET) -l setup/winvers-change bundle/racket UPLOAD_q = --readme "$(README)" --upload "$(UPLOAD)" --desc "$(DIST_DESC)" DIST_ARGS_q = $(UPLOAD_q) $(RELEASE_MODE) $(SOURCE_MODE) $(VERSIONLESS_MODE) $(MAC_PKG_MODE) \ diff --git a/racket/collects/setup/winvers-change.rkt b/racket/collects/setup/winvers-change.rkt index ab229abb05..c841f61bc7 100644 --- a/racket/collects/setup/winvers-change.rkt +++ b/racket/collects/setup/winvers-change.rkt @@ -9,6 +9,7 @@ ;; of the binary and restarting that copy for the actual change. #lang racket/base +(require setup/cross-system) (define verbose? #t) (define binary-extensions '("exe" "dll" "lib" "so" "def" "exp" #|"obj" "o"|#)) @@ -69,12 +70,13 @@ (close-input-port i) (close-output-port o))) -(let loop ([paths (if (zero? (vector-length (current-command-line-arguments))) - '(".") - (vector->list (current-command-line-arguments)))]) - (for ([path (in-list paths)]) - (cond [(file-exists? path) - (when (binary-file? path) (do-file path))] - [(directory-exists? path) - (parameterize ([current-directory path]) - (loop (map path->string (directory-list))))]))) +(when (eq? 'windows (cross-system-type)) + (let loop ([paths (if (zero? (vector-length (current-command-line-arguments))) + '(".") + (vector->list (current-command-line-arguments)))]) + (for ([path (in-list paths)]) + (cond [(file-exists? path) + (when (binary-file? path) (do-file path))] + [(directory-exists? path) + (parameterize ([current-directory path]) + (loop (map path->string (directory-list))))])))) From 7cffdca067c294200e57c4298effce5e02cfc932 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 19 Oct 2015 17:40:37 -0600 Subject: [PATCH 340/381] work around an access() problem on Mac OS X ... again. Merge to v6.3 --- racket/src/racket/src/file.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index 2d9c6efcb7..b892d78529 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -6143,7 +6143,11 @@ static Scheme_Object *file_or_dir_permissions(int argc, Scheme_Object *argv[]) } while ((ok == -1) && (errno == EINTR)); write = !ok; - if (ok && (errno != EACCES)) + /* Don't fail at the exec step if errno is EPERM; under Mac OS + X, at least, such a failure seems to mean that the file is + not writable. (We assume it's not a directory-access issue, + since the read test succeeded.) */ + if (ok && (errno != EACCES) && (errno != EPERM)) l = NULL; else { do { From dad280441201c37e036a3182dc20d8944975633b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 19 Oct 2015 19:40:12 -0600 Subject: [PATCH 341/381] make MinGW build use the `LIBS` environment variable Merge to v6.3 --- racket/src/racket/Makefile.in | 4 ++-- racket/src/racket/gc2/Makefile.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 78935c77d0..b6c93a0673 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -212,14 +212,14 @@ racket@CGC@@OSX@: $(MZFW) main.@LTO@ lib/libmzgcxxxxxxx.dll: libmzgc.@LIBSFX@ mkdir -p lib - @MZLINKER@ -shared -o lib/libmzgcxxxxxxx.dll -Wl,--output-def -Wl,libmzgc.def -Wl,--whole-archive libmzgc.@LIBSFX@ -Wl,--no-whole-archive -static-libgcc + @MZLINKER@ -shared -o lib/libmzgcxxxxxxx.dll -Wl,--output-def -Wl,libmzgc.def -Wl,--whole-archive libmzgc.@LIBSFX@ -Wl,--no-whole-archive @LDFLAGS@ -static-libgcc @LIBS@ mzsj86g.o: $(srcdir)/src/mzsj86g.S $(CC) -c -o mzsj86g.o $(srcdir)/src/mzsj86g.S lib/libracketxxxxxxx.dll: lib/libmzgcxxxxxxx.dll libracket.@LIBSFX@ mzsj86g.o mkdir -p lib - @MZLINKER@ -shared -o lib/libracketxxxxxxx.dll mzsj86g.o -Wl,--output-def -Wl,libracket.def -Wl,--whole-archive libracket.@LIBSFX@ -Wl,--no-whole-archive -lshell32 -luser32 -lws2_32 lib/libmzgcxxxxxxx.dll -static-libgcc + @MZLINKER@ -shared -o lib/libracketxxxxxxx.dll mzsj86g.o -Wl,--output-def -Wl,libracket.def -Wl,--whole-archive libracket.@LIBSFX@ -Wl,--no-whole-archive @LDFLAGS@ -lshell32 -luser32 -lws2_32 lib/libmzgcxxxxxxx.dll -static-libgcc @LIBS@ libracket.dll.a: lib/libracketxxxxxxx.dll @DLLTOOL@ --def libracket.def -D libracketxxxxxxx.dll --output-exp libracketxxxxxxx.exp --output-lib libracketxxxxxxx.lib --output-delaylib libracket.dll.a diff --git a/racket/src/racket/gc2/Makefile.in b/racket/src/racket/gc2/Makefile.in index 4b5c53545a..2f23ff75a4 100644 --- a/racket/src/racket/gc2/Makefile.in +++ b/racket/src/racket/gc2/Makefile.in @@ -526,7 +526,7 @@ $(MZFWMMM): ../libracket3m.@LIBSFX@ ../lib/libracket3mxxxxxxx.dll: ../libracket3m.@LIBSFX@ ../mzsj86g.o mkdir -p ../lib - @MZLINKER@ -shared -o ../lib/libracket3mxxxxxxx.dll ../mzsj86g.o -Wl,--output-def -Wl,libracket3m.def -Wl,--whole-archive ../libracket3m.@LIBSFX@ -Wl,--no-whole-archive -lshell32 -luser32 -lws2_32 -static-libgcc + @MZLINKER@ -shared -o ../lib/libracket3mxxxxxxx.dll ../mzsj86g.o -Wl,--output-def -Wl,libracket3m.def -Wl,--whole-archive ../libracket3m.@LIBSFX@ -Wl,--no-whole-archive @LDFLAGS@ -lshell32 -luser32 -lws2_32 -static-libgcc @LIBS@ libracket3m.dll.a: ../lib/libracket3mxxxxxxx.dll @DLLTOOL@ --def libracket3m.def -D libracket3mxxxxxxx.dll --output-exp libracket3mxxxxxxx.exp --output-lib libracket3mxxxxxxx.lib --output-delaylib libracket3m.dll.a From dfab18fe4729e71f53d0056572e3f85a72467247 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 08:31:29 -0600 Subject: [PATCH 342/381] configure: infer static linking of libwinpthread for MinGW Merge to v6.3 --- racket/src/configure | 46 ++++++++++++++++++++++++++++++++++ racket/src/racket/configure.ac | 5 ++++ 2 files changed, 51 insertions(+) diff --git a/racket/src/configure b/racket/src/configure index 87f48a7c2c..dbc52ea48d 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -4674,6 +4674,52 @@ $as_echo "#define HAVE_STDINT_H 1" >>confdefs.h if `which ${host}-dlltool > /dev/null` ; then DLLTOOL="${host}-dlltool" fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lwinpthread" >&5 +$as_echo_n "checking for pthread_create in -lwinpthread... " >&6; } +if ${ac_cv_lib_winpthread_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lwinpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_winpthread_pthread_create=yes +else + ac_cv_lib_winpthread_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_winpthread_pthread_create" >&5 +$as_echo "$ac_cv_lib_winpthread_pthread_create" >&6; } +if test "x$ac_cv_lib_winpthread_pthread_create" = xyes; then : + has_winpthread=yes +else + has_winpthread=no +fi + + if test "${has_winpthread}" == "yes" ; then + LIBS="${LIBS} -Wl,-Bstatic -lwinpthread" + fi case "$build_os" in *cygwin*) PWD="cygpath -m \\\`pwd\\\`" diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index d778329f93..46b76c953f 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -796,6 +796,11 @@ case "$host_os" in if `which ${host}-dlltool > /dev/null` ; then DLLTOOL="${host}-dlltool" fi + + AC_CHECK_LIB(winpthread, pthread_create, has_winpthread=yes, has_winpthread=no) + if test "${has_winpthread}" == "yes" ; then + LIBS="${LIBS} -Wl,-Bstatic -lwinpthread" + fi case "$build_os" in *cygwin*) PWD="cygpath -m \\\`pwd\\\`" From 10b3e8040aeae137786f5327b69f72226c06663c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 15:02:54 -0600 Subject: [PATCH 343/381] extra version-number pattern for Windows versioning --- racket/collects/setup/winvers-change.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/racket/collects/setup/winvers-change.rkt b/racket/collects/setup/winvers-change.rkt index c841f61bc7..77ca662f85 100644 --- a/racket/collects/setup/winvers-change.rkt +++ b/racket/collects/setup/winvers-change.rkt @@ -25,6 +25,7 @@ #"~a_NULL_THUNK_DATA\0" #"__IMPORT_DESCRIPTOR_~a\0" #"__head_~a_lib\0" + #"_head_~a_lib\0" #"__~a_lib_iname\0"))) (require dynext/filename-version) From 5d74897aa48795285c576d668388a866d9f1a830 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 15:37:22 -0600 Subject: [PATCH 344/381] always install static "mzconfig.h" for Windows --- racket/src/racket/Makefile.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index b6c93a0673..af6d2e49e3 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -314,8 +314,11 @@ total_startup: mv src/schminc.newh src/schminc.h $(MAKE) cgc +MZCONFIGDIR@NOT_MINGW@ = . +MZCONFIGDIR@MINGW@ = "$(srcdir)/../worksp" + headers: - @RUN_RACKET_CGC@ -cqu $(srcdir)/mkincludes.rkt @DIRCVTPRE@"$(DESTDIR)$(includepltdir)"@DIRCVTPOST@ "$(srcdir)" . + @RUN_RACKET_CGC@ -cqu $(srcdir)/mkincludes.rkt @DIRCVTPRE@"$(DESTDIR)$(includepltdir)"@DIRCVTPOST@ "$(srcdir)" $(MZCONFIGDIR) cd ..; cp racket/system.rktd "$(DESTDIR)$(libpltdir)/system.rktd" $(srcdir)/src/schexn.h: $(srcdir)/src/makeexn From b8ba78d1d3a8e85bd623f2e092bd774f388af808 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 15:39:28 -0600 Subject: [PATCH 345/381] avoid slow TLS with MinGW Recent versions of MinGW-W64 use emutls for `__thread` variables, and that's much slower than Windows-native TLS. Go back to the inline-assembly implementation of therad-local access. --- racket/src/racket/include/schthread.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/racket/src/racket/include/schthread.h b/racket/src/racket/include/schthread.h index d7d35352cd..2ff040cc54 100644 --- a/racket/src/racket/include/schthread.h +++ b/racket/src/racket/include/schthread.h @@ -30,12 +30,13 @@ extern "C" { # ifdef _WIN32 # if defined(_WIN64) # if defined(__MINGW32__) -# define THREAD_LOCAL __thread +# define THREAD_LOCAL /* empty */ +# define IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS # else # define THREAD_LOCAL __declspec(thread) +# define MZ_THREAD_EXTERN extern +# define IMPLEMENT_THREAD_LOCAL_EXTERNALLY_VIA_PROC # endif -# define MZ_THREAD_EXTERN extern -# define IMPLEMENT_THREAD_LOCAL_EXTERNALLY_VIA_PROC # else # define THREAD_LOCAL /* empty */ # define IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS From 5056e5fd1baaec162c713440ad4223f0a7698c7c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 16:06:41 -0600 Subject: [PATCH 346/381] provide ".def" file for the Racket DLL A ".def" file is compiler-independent. --- racket/collects/setup/winvers-change.rkt | 2 +- racket/src/racket/Makefile.in | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/racket/collects/setup/winvers-change.rkt b/racket/collects/setup/winvers-change.rkt index 77ca662f85..1904e1c3c2 100644 --- a/racket/collects/setup/winvers-change.rkt +++ b/racket/collects/setup/winvers-change.rkt @@ -16,7 +16,7 @@ (define xxxs #"xxxxxxx") (define xxxs-re (bytes-append #"(?:lib(?:g?racket|mzgc)(?:|3m))(" xxxs #")")) -(define renaming (regexp (format "^~a[.](?:dll|lib|exp)$" xxxs-re))) +(define renaming (regexp (format "^~a[.](?:dll|lib|exp|def)$" xxxs-re))) (define substitutions (map (lambda (s) (byte-regexp (regexp-replace #rx#"~a" s xxxs-re))) ;; pdb not needed, but this way we can expect no diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index af6d2e49e3..1180a6b4d9 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -453,8 +453,10 @@ mingw-install-cgc: cd ..; mkdir -p "$(DESTDIR)$(libdir)/msvc" cd ..; $(ICP) racket/libmzgcxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libmzgcxxxxxxx.lib" cd ..; $(ICP) racket/libmzgcxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libmzgcxxxxxxx.exp" + cd ..; $(ICP) racket/libmzgc.def "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.def" cd ..; $(ICP) racket/libracketxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libracketxxxxxxx.lib" cd ..; $(ICP) racket/libracketxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libracketxxxxxxx.exp" + cd ..; $(ICP) racket/libracket.def "$(DESTDIR)$(libdir)/libracketxxxxxxx.def" cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/msvc/mzdyn.obj" cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/msvc/mzdyn.exp" cd ..; $(ICP) racket/lib/libmzgcxxxxxxx.dll "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" @@ -474,6 +476,7 @@ mingw-install-3m: cd ..; mkdir -p "$(DESTDIR)$(libdir)/msvc" cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libracket3mxxxxxxx.lib" cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libracket3mxxxxxxx.exp" + cd ..; $(ICP) racket/gc2/libracket3m.def "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.def" cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/msvc/mzdyn3m.obj" cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/msvc/mzdyn3m.exp" cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" From 0e924525eeadb6670a53b79a6c2f946a04e42184 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 17:11:23 -0600 Subject: [PATCH 347/381] MinGW build: put ".lib", ".exp", and ".obj" in the right place Those files are compiler-specific, so they should be in a "gcc" subdirectory instead of "msvc". --- racket/src/racket/Makefile.in | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 1180a6b4d9..4e578bb1e5 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -450,15 +450,15 @@ mingw-install: cd ..; cp racket/MzCOM.tlb "$(DESTDIR)$(libpltdir)/MzCOM.tlb" mingw-install-cgc: - cd ..; mkdir -p "$(DESTDIR)$(libdir)/msvc" - cd ..; $(ICP) racket/libmzgcxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libmzgcxxxxxxx.lib" - cd ..; $(ICP) racket/libmzgcxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libmzgcxxxxxxx.exp" + cd ..; mkdir -p "$(DESTDIR)$(libdir)/gcc" + cd ..; $(ICP) racket/libmzgcxxxxxxx.lib "$(DESTDIR)$(libdir)/gcc/libmzgcxxxxxxx.lib" + cd ..; $(ICP) racket/libmzgcxxxxxxx.exp "$(DESTDIR)$(libdir)/gcc/libmzgcxxxxxxx.exp" cd ..; $(ICP) racket/libmzgc.def "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.def" - cd ..; $(ICP) racket/libracketxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libracketxxxxxxx.lib" - cd ..; $(ICP) racket/libracketxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libracketxxxxxxx.exp" + cd ..; $(ICP) racket/libracketxxxxxxx.lib "$(DESTDIR)$(libdir)/gcc/libracketxxxxxxx.lib" + cd ..; $(ICP) racket/libracketxxxxxxx.exp "$(DESTDIR)$(libdir)/gcc/libracketxxxxxxx.exp" cd ..; $(ICP) racket/libracket.def "$(DESTDIR)$(libdir)/libracketxxxxxxx.def" - cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/msvc/mzdyn.obj" - cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/msvc/mzdyn.exp" + cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/gcc/mzdyn.obj" + cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/gcc/mzdyn.exp" cd ..; $(ICP) racket/lib/libmzgcxxxxxxx.dll "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll" cd ..; $(ICP) racket/lib/libracketxxxxxxx.dll "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll" cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" @@ -473,12 +473,12 @@ mingw-install-cgc-final: $(NOOP) mingw-install-3m: - cd ..; mkdir -p "$(DESTDIR)$(libdir)/msvc" - cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.lib "$(DESTDIR)$(libdir)/msvc/libracket3mxxxxxxx.lib" - cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.exp "$(DESTDIR)$(libdir)/msvc/libracket3mxxxxxxx.exp" + cd ..; mkdir -p "$(DESTDIR)$(libdir)/gcc" + cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.lib "$(DESTDIR)$(libdir)/gcc/libracket3mxxxxxxx.lib" + cd ..; $(ICP) racket/gc2/libracket3mxxxxxxx.exp "$(DESTDIR)$(libdir)/gcc/libracket3mxxxxxxx.exp" cd ..; $(ICP) racket/gc2/libracket3m.def "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.def" - cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/msvc/mzdyn3m.obj" - cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/msvc/mzdyn3m.exp" + cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libdir)/gcc/mzdyn3m.obj" + cd ..; $(ICP) racket/mzdyn3m.exp "$(DESTDIR)$(libdir)/gcc/mzdyn3m.exp" cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(ICP) racket/mzcom@MMM@ "$(DESTDIR)$(libdir)/MzCOM@MMM_INSTALLED@@EXE_SUFFIX@" cd ..; $(ICP) racket/lib/libracket3mxxxxxxx.dll "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll" From 8620f95763a090d3c82d50515b82fed6dd34d2f2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 17:17:05 -0600 Subject: [PATCH 348/381] Windows distribution: remove compiler-specific libraries Building creates compiler-specific files in "lib/msvc" or "lib/gcc". For consistency, strip those directories when creating a distribution. The newly added ".def" file provides information that would otherwise be lost by removing the MSVC ".lib" file from the distribution. Removing the compiler-specific ".obj" files means that used to be included for linking extensions. My guess is that the files are now completely unused. --- Makefile | 1 + racket/collects/setup/winstrip.rkt | 49 +++++++++++++++++++----------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 6feaba96e2..80b805ef1f 100644 --- a/Makefile +++ b/Makefile @@ -492,6 +492,7 @@ bundle-from-server: $(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(REQUIRED_PKGS) $(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(PKGS) $(RACKET) -l setup/unixstyle-install post-adjust "$(SOURCE_MODE)" "$(PKG_SOURCE_MODE)" racket bundle/racket + $(RACKET) -l setup/winstrip bundle/racket $(RACKET) -l setup/winvers-change bundle/racket UPLOAD_q = --readme "$(README)" --upload "$(UPLOAD)" --desc "$(DIST_DESC)" diff --git a/racket/collects/setup/winstrip.rkt b/racket/collects/setup/winstrip.rkt index c8edff1666..f0990f3d68 100644 --- a/racket/collects/setup/winstrip.rkt +++ b/racket/collects/setup/winstrip.rkt @@ -1,5 +1,7 @@ #lang racket/base -(require racket/cmdline) +(require racket/cmdline + setup/cross-system + racket/file) (module test racket/base) @@ -20,23 +22,34 @@ (printf "Deleting ~a\n" p) (delete-file p)) -(for ([a (directory-list dir)]) - (define f (build-path dir a)) - (define b (path-element->bytes a)) - (when (and (file-exists? f) - (or (regexp-match? #rx#"[.](?i:pdb|ilk)$" b) - (regexp-match? #rx#"(?i:CGC[.]exe)$" b))) - (delete-file* f))) +(when (eq? 'windows (cross-system-type)) + (for ([a (directory-list dir)]) + (define f (build-path dir a)) + (define b (path-element->bytes a)) + (when (and (file-exists? f) + (or (regexp-match? #rx#"[.](?i:pdb|ilk)$" b) + (regexp-match? #rx#"(?i:CGC[.]exe)$" b))) + (delete-file* f))) + + (for ([f (in-directory (build-path dir "lib"))]) + (when (and (file-exists? f) + (let ([b (path-element->bytes + (let-values ([(base name dir?) (split-path f)]) + name))]) + (or (regexp-match? #rx#"[.](?i:pdb|ilk|manifest)$" b) + (regexp-match? #rx#"(?i:CGC[.](?:dll|exe))$" b) + (and (regexp-match? #rx#"(?i:[.](?:dll|exp|obj|lib))$" b) + (not (regexp-match? #rx#"3m" b)))))) + (delete-file* f))) + + ;; Delete any subdirectory that contains ".lib" files. + ;; Those are compiler-specific directories, and so we + ;; don't want to include them in a distribution. + (for ([f (in-directory (build-path dir "lib"))]) + (when (and (directory-exists? f) + (for/or ([f (in-directory f)]) + (regexp-match? #rx"[.]lib$" f))) + (delete-directory/files f)))) -(for ([f (in-directory (build-path dir "lib"))]) - (when (and (file-exists? f) - (let ([b (path-element->bytes - (let-values ([(base name dir?) (split-path f)]) - name))]) - (or (regexp-match? #rx#"[.](?i:pdb|ilk|manifest)$" b) - (regexp-match? #rx#"(?i:CGC[.](?:dll|exe))$" b) - (and (regexp-match? #rx#"(?i:[.](?:dll|exp|obj|lib))$" b) - (not (regexp-match? #rx#"3m" b)))))) - (delete-file* f))) From ea6cef5246abd18142ebd8b3d04b8a02d29e4869 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 18:37:28 -0600 Subject: [PATCH 349/381] Windows: make scheme_register_tls_space() always available To make the API consistent for MSVC versus MinGW builds, make a functional formerly required for embedding on 32-bit Windows always available and required for all Windows variants. --- pkgs/racket-doc/scribblings/inside/embedding.scrbl | 9 +++++++-- pkgs/racket-doc/scribblings/inside/memory.scrbl | 7 +++++-- racket/src/racket/include/scheme.h | 2 -- racket/src/racket/src/salloc.c | 5 +++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/inside/embedding.scrbl b/pkgs/racket-doc/scribblings/inside/embedding.scrbl index 2064ca5831..96c0c58433 100644 --- a/pkgs/racket-doc/scribblings/inside/embedding.scrbl +++ b/pkgs/racket-doc/scribblings/inside/embedding.scrbl @@ -87,7 +87,7 @@ To embed Racket CGC in a program, follow these steps: @cpp{scheme_main_stack_setup} trampoline registers the C stack with the memory manager without creating a namespace.) - On 32-bit Windows, when support for parallelism is enabled in the Racket + On Windows, when support for parallelism is enabled in the Racket build (as is the default), then before calling @cpp{scheme_main_setup}, your embedding application must first call @cppi{scheme_register_tls_space}: @@ -101,7 +101,12 @@ To embed Racket CGC in a program, follow these steps: @verbatim[#:indent 2]{ static __declspec(thread) void *tls_space; - }} + } + + @history[#:changed "6.3" @elem{Calling @cpp{scheme_register_tls_space} is + required on all Windows variants, although the call + may be a no-op, depending on how Racket is + built.}]} @item{Configure the namespace by adding module declarations. The initial namespace contains declarations only for a few primitive diff --git a/pkgs/racket-doc/scribblings/inside/memory.scrbl b/pkgs/racket-doc/scribblings/inside/memory.scrbl index b010d2d1f8..eabedce650 100644 --- a/pkgs/racket-doc/scribblings/inside/memory.scrbl +++ b/pkgs/racket-doc/scribblings/inside/memory.scrbl @@ -899,7 +899,7 @@ overflow.} [void* ptr] [int tls_index])]{ -Only available on 32-bit Windows; registers @var{ptr} as the address of a +For Windows, registers @var{ptr} as the address of a thread-local pointer variable that is declared in the main executable. The variable's storage will be used to implement thread-local storage within the Racket run-time. See @@ -908,7 +908,10 @@ Only available on 32-bit Windows; registers @var{ptr} as the address of a The @var{tls_index} argument must be @cpp{0}. It is currently ignored, but a future version may use the argument to allow declaration of the thread-local variable in a dynamically linked - DLL.} + DLL. + +@history[#:changed "6.3" @elem{Changed from available only on 32-bit Windows + to available on all Windows variants.}]} @function[(void scheme_register_static [void* ptr] diff --git a/racket/src/racket/include/scheme.h b/racket/src/racket/include/scheme.h index 1563826591..1ede3d0c9b 100644 --- a/racket/src/racket/include/scheme.h +++ b/racket/src/racket/include/scheme.h @@ -1982,9 +1982,7 @@ MZ_EXTERN int scheme_main_stack_setup(int no_auto_statics, Scheme_Nested_Main _m typedef int (*Scheme_Env_Main)(Scheme_Env *env, int argc, char **argv); MZ_EXTERN int scheme_main_setup(int no_auto_statics, Scheme_Env_Main _main, int argc, char **argv); -#ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS MZ_EXTERN void scheme_register_tls_space(void *tls_space, int _tls_index); -#endif MZ_EXTERN void scheme_register_static(void *ptr, intptr_t size); #if defined(MUST_REGISTER_GLOBALS) || defined(GC_MIGHT_USE_REGISTERED_STATICS) diff --git a/racket/src/racket/src/salloc.c b/racket/src/racket/src/salloc.c index 5e4130fbf0..2c449cba8a 100644 --- a/racket/src/racket/src/salloc.c +++ b/racket/src/racket/src/salloc.c @@ -223,6 +223,11 @@ Thread_Local_Variables *scheme_external_get_thread_local_variables() XFORM_SKIP_ { return scheme_get_thread_local_variables(); } +#else +void scheme_register_tls_space(void *tls_space, int tls_index) XFORM_SKIP_PROC +{ + /* Nothing to do; provided for compatibility. */ +} #endif #ifdef IMPLEMENT_THREAD_LOCAL_EXTERNALLY_VIA_PROC From a38ba440fa327680dbac515cee5703b5e4d23557 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 19:17:47 -0600 Subject: [PATCH 350/381] add ".def" generation for MSVC build --- racket/src/worksp/build.bat | 3 +++ racket/src/worksp/gendef.rkt | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 racket/src/worksp/gendef.rkt diff --git a/racket/src/worksp/build.bat b/racket/src/worksp/build.bat index 098c953089..c95cb38468 100644 --- a/racket/src/worksp/build.bat +++ b/racket/src/worksp/build.bat @@ -63,3 +63,6 @@ if errorlevel 1 exit /B 1 ..\..\racket -G %BUILD_CONFIG% -N "raco" %SELF_RACKET_FLAGS% -l- setup %PLT_SETUP_OPTIONS% if errorlevel 1 exit /B 1 + +..\..\racket -G ..\%BUILD_CONFIG% -u gendef.rkt +if errorlevel 1 exit /B 1 diff --git a/racket/src/worksp/gendef.rkt b/racket/src/worksp/gendef.rkt new file mode 100644 index 0000000000..3c37bdb5e2 --- /dev/null +++ b/racket/src/worksp/gendef.rkt @@ -0,0 +1,30 @@ +;; Generate ".def" files for installed DLLs +#lang racket/base +(require racket/system) + +(define lib-dir (build-path 'up 'up "lib")) + +(define (gen-one name) + (define f (build-path lib-dir (format "~axxxxxxx.dll" name))) + (when (file-exists? f) + (define s (open-output-bytes)) + (parameterize ([current-output-port s]) + (system (format "dumpbin /exports ~a" f))) + (define i (open-input-bytes (get-output-bytes s))) + (regexp-match #rx"ordinal +hint +RVA +name" i) + (call-with-output-file* + (build-path lib-dir (format "~axxxxxxx.def" name)) + #:exists 'truncate + (lambda (o) + (fprintf o "EXPORTS\n") + (for ([l (in-lines i)]) + (define m (regexp-match + #rx"([0-9]+) +(?:[0-9A-Fa-f]+) +(?:[0-9A-Fa-f]+) +([_A-Za-z][_A-Za-z0-9]*) +=" + l)) + (when m + (fprintf o " ~a @~a\n" (caddr m) (cadr m)))))))) + +(gen-one "libmzgc") +(gen-one "libracket") +(gen-one "libracket3m") + From 5a768de1328d54e50ba7960d4a59e5d02bef7f15 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 19:20:43 -0600 Subject: [PATCH 351/381] fix Windows distribution stripping to remove CGC ".def" files --- racket/collects/setup/winstrip.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/collects/setup/winstrip.rkt b/racket/collects/setup/winstrip.rkt index f0990f3d68..4259f537ea 100644 --- a/racket/collects/setup/winstrip.rkt +++ b/racket/collects/setup/winstrip.rkt @@ -38,7 +38,7 @@ name))]) (or (regexp-match? #rx#"[.](?i:pdb|ilk|manifest)$" b) (regexp-match? #rx#"(?i:CGC[.](?:dll|exe))$" b) - (and (regexp-match? #rx#"(?i:[.](?:dll|exp|obj|lib))$" b) + (and (regexp-match? #rx#"(?i:[.](?:dll|exp|obj|lib|def))$" b) (not (regexp-match? #rx#"3m" b)))))) (delete-file* f))) From 7b7a3157771680e8b4ba8e18bab798280e052711 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 Oct 2015 19:38:39 -0600 Subject: [PATCH 352/381] fix taint-check ordering in expander Merge to v6.3 --- pkgs/racket-test-core/tests/racket/macro.rktl | 11 +++++++++++ racket/src/racket/src/compenv.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/macro.rktl b/pkgs/racket-test-core/tests/racket/macro.rktl index fa156577cb..33f6fadd34 100644 --- a/pkgs/racket-test-core/tests/racket/macro.rktl +++ b/pkgs/racket-test-core/tests/racket/macro.rktl @@ -1553,6 +1553,17 @@ (test 'outer dynamic-require ''should-be-outer-4 'd) +;; ---------------------------------------- +;; Check that taint check precedes bound-with-binding substitution: + +(err/rt-test (expand '(let ([x 1]) + (let-syntax ([m (lambda (stx) + #`(list #,(syntax-taint #'x)))]) + (m)))) + (lambda (exn) + (regexp-match? #rx"cannot use identifier tainted by macro transformation" + (exn-message exn)))) + ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index 4dc3a8f05a..1c239e965a 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -1257,9 +1257,9 @@ scheme_compile_lookup(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, for (i = frame->num_bindings; i--; ) { if (frame->bindings[i] && SAME_OBJ(binding, frame->bindings[i])) { /* Found a lambda-, let-, etc. bound variable: */ + check_taint(find_id); if (_binder) set_binder(_binder, find_id, frame->binders[i]); - check_taint(find_id); if (!frame->vals) { if (flags & SCHEME_DONT_MARK_USE) From 62f089756cf9abc6ff5a98a2ffedeed02e3065cf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 21 Oct 2015 15:16:56 -0600 Subject: [PATCH 353/381] fix doc typo --- pkgs/racket-doc/scribblings/reference/stx-trans.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index e44b5aab10..838031d524 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -976,7 +976,7 @@ identifiers. Each list of identifiers includes all bindings imported (into the module being expanded) using the module path @racket[mod-path], or all modules if @racket[mod-path] is @racket[#f]. The association list includes all identifiers imported -with a @racket[phase-level] shift, of all shifts if +with a @racket[phase-level] shift, or all shifts if @racket[phase-level] is @racket[#t]. When an identifier is renamed on import, the result association list From 876708c100695392a3f054b786646007f2487f75 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 21 Oct 2015 16:50:37 -0600 Subject: [PATCH 354/381] fix tracking of shadowed module imports When an import is shadowed by another import or by a definition, don't include it in the set of bindings in the resut of `syntax-local-module-required-identifiers` or in the set that can be exported by `all-from-out`. Merge to v6.3 --- .../racket-test-core/tests/racket/module.rktl | 28 +++++++++++++++++++ racket/collects/racket/signature/lang.rkt | 3 +- racket/src/racket/src/module.c | 10 ++++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 1d292d43bc..44dda840c1 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1575,4 +1575,32 @@ case of module-leve bindings; it doesn't cover local bindings. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(module shadows-a-racket-base-binding-and-exports racket/base + (provide (all-defined-out)) ; exports `path?` + (struct path ())) + +(module import-shadows-a-racket-base-binding racket/base + (require 'shadows-a-racket-base-binding-and-exports) + (provide (all-from-out racket/base))) + +;; Fails because imported module doesn't provide `path?`: +(syntax-test #'(module m racket/base + (require (rename-in 'import-shadows-a-racket-base-binding + [path? other-path?])))) + +(module import-shadows-a-racket-base-binding-and-doesnt-confuse-struct-out racket/base + (require 'shadows-a-racket-base-binding-and-exports) + (provide (struct-out path))) + +(module shadows-a-racket-base-binding-and-exports-all racket/base + (provide (all-from-out racket/base)) ; does not export `path?` + (struct path ())) + +(syntax-test #'(module m racket/base + (require (rename-in 'shadows-a-racket-base-binding-and-exports-all + [path? other-path?])))) + + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (report-errs) diff --git a/racket/collects/racket/signature/lang.rkt b/racket/collects/racket/signature/lang.rkt index 86aeb76414..771ff7dd69 100644 --- a/racket/collects/racket/signature/lang.rkt +++ b/racket/collects/racket/signature/lang.rkt @@ -10,8 +10,7 @@ (provide (rename-out [module-begin #%module-begin] [struct~s struct]) (except-out (all-from-out racket/base) - #%module-begin - struct) + #%module-begin) (all-from-out racket/unit) (all-from-out racket/contract) (for-syntax (all-from-out racket/base))) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index c2770b925a..4cf6cedf0a 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7573,8 +7573,8 @@ static void check_require_name(Scheme_Object *id, Scheme_Object *self_modidx, if (!scheme_hash_get(required, SCHEME_STX_VAL(id))) { /* no mapping so far means that we haven't imported anything - with this name so far, and we'll be able to use a symbol a - sumbol as a key; see require_binding_to_key() */ + with this name so far, and we'll be able to use a symbol + as a key; see require_binding_to_key() */ binding = SCHEME_STX_VAL(id); } else { /* Look for import collisions by checking whether `id` has a binding; @@ -7602,7 +7602,7 @@ static void check_require_name(Scheme_Object *id, Scheme_Object *self_modidx, } else { binding = require_binding_to_key(required, binding, SCHEME_STX_VAL(id)); if (scheme_hash_get(required, binding)) { - /* use error report below */ + /* use error report or override below */ } else { /* identifier has a binding in some context, but not within the current module */ binding = NULL; @@ -7659,7 +7659,9 @@ static void check_require_name(Scheme_Object *id, Scheme_Object *self_modidx, if (SCHEME_TRUEP(SCHEME_VEC_ELS(vec)[7]) && prep_required_id(vec) && scheme_stx_bound_eq(SCHEME_VEC_ELS(vec)[6], id, phase)) { - /* can override; construct overriding `binding` */ + /* can override; first, remove old binding mapping: */ + scheme_hash_set(required, binding, NULL); + /* construct overriding `binding`: */ binding = scheme_make_vector(4, NULL); vec = scheme_module_resolve(modidx, 0); SCHEME_VEC_ELS(binding)[0] = vec; From 91d825ba61805d93673adcd8c9aadc37af8fddf9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 21 Oct 2015 18:12:05 -0600 Subject: [PATCH 355/381] Windows cross-build: fix over-agressive pruning of DLLs The `setup/winstrip` step was run too late. As an extra measure, make make `setup/winstrip` more precise about the files it will discard. Merge to v6.3 --- Makefile | 4 ++-- racket/collects/setup/winstrip.rkt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 80b805ef1f..50e6312fd5 100644 --- a/Makefile +++ b/Makefile @@ -488,12 +488,12 @@ bundle-from-server: rm -rf bundle mkdir -p bundle/racket $(RACKET) -l setup/unixstyle-install bundle racket bundle/racket + $(RACKET) -l setup/winstrip bundle/racket + $(RACKET) -l setup/winvers-change bundle/racket $(RACKET) -l distro-build/unpack-collects http://$(SVR_PRT)/$(SERVER_COLLECTS_PATH) $(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(REQUIRED_PKGS) $(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(PKGS) $(RACKET) -l setup/unixstyle-install post-adjust "$(SOURCE_MODE)" "$(PKG_SOURCE_MODE)" racket bundle/racket - $(RACKET) -l setup/winstrip bundle/racket - $(RACKET) -l setup/winvers-change bundle/racket UPLOAD_q = --readme "$(README)" --upload "$(UPLOAD)" --desc "$(DIST_DESC)" DIST_ARGS_q = $(UPLOAD_q) $(RELEASE_MODE) $(SOURCE_MODE) $(VERSIONLESS_MODE) $(MAC_PKG_MODE) \ diff --git a/racket/collects/setup/winstrip.rkt b/racket/collects/setup/winstrip.rkt index 4259f537ea..a1207c5fd8 100644 --- a/racket/collects/setup/winstrip.rkt +++ b/racket/collects/setup/winstrip.rkt @@ -39,6 +39,7 @@ (or (regexp-match? #rx#"[.](?i:pdb|ilk|manifest)$" b) (regexp-match? #rx#"(?i:CGC[.](?:dll|exe))$" b) (and (regexp-match? #rx#"(?i:[.](?:dll|exp|obj|lib|def))$" b) + (regexp-match? #rx#"(?i:racket|mzgc)$" b) (not (regexp-match? #rx#"3m" b)))))) (delete-file* f))) From b98731ed008019c476185c012d955d1aadfb81ef Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 22 Oct 2015 09:39:48 -0600 Subject: [PATCH 356/381] Windows cross-build: MzCOM as a GUI executable Merge to v6.3 --- racket/src/racket/Makefile.in | 2 +- racket/src/racket/gc2/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/Makefile.in b/racket/src/racket/Makefile.in index 4e578bb1e5..8c52c7ba34 100644 --- a/racket/src/racket/Makefile.in +++ b/racket/src/racket/Makefile.in @@ -242,7 +242,7 @@ mingw-other@NOT_MINGW@: $(NOOP) mzcom@CGC@@MINGW@: libracket.dll.a libmzgc.dll.a mzcom.@LTO@ mzobj.@LTO@ com_glue.@LTO@ $(SPECIALIZINGOBJECTS) comres.o - @MZLINKER@ -o mzcom@CGC@ mzcom.@LTO@ mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS) + @MZLINKER@ -mwindows -o mzcom@CGC@ mzcom.@LTO@ mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS) comres.o : $(srcdir)/../worksp/mzcom/mzcom.rc $(srcdir)/../mzcom/prebuilt/MzCOM.tlb @WINDRES@ -I $(srcdir)/../mzcom -I $(srcdir)/../mzcom/prebuilt -i $(srcdir)/../worksp/mzcom/mzcom.rc -o comres.o diff --git a/racket/src/racket/gc2/Makefile.in b/racket/src/racket/gc2/Makefile.in index 2f23ff75a4..5b7d7eab0c 100644 --- a/racket/src/racket/gc2/Makefile.in +++ b/racket/src/racket/gc2/Makefile.in @@ -540,7 +540,7 @@ MW_RACKET_LIBS = gc2/libracket3m.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgc $(NOOP) ../mzcom@MMM@@MINGW@: libracket3m.dll.a mzcom.@LTO@ mzobj.@LTO@ ../com_glue.@LTO@ $(SPECIALIZINGOBJECTS) ../comres.o - cd ..; @MZLINKER@ -o mzcom@MMM@ gc2/mzcom.@LTO@ gc2/mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS) + cd ..; @MZLINKER@ -mwindows -o mzcom@MMM@ gc2/mzcom.@LTO@ gc2/mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS) clean: /bin/rm -f ../racket@MMM@ *.@LTO@ $(XSRCDIR)/* From 2e3ff0332d99a926ea05321d1aa76cef44508078 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 22 Oct 2015 09:40:37 -0600 Subject: [PATCH 357/381] improve docs on `make-weak-hash` Note that values are held normally and ephemerons can help. --- pkgs/racket-doc/scribblings/reference/hashes.scrbl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/hashes.scrbl b/pkgs/racket-doc/scribblings/reference/hashes.scrbl index b5b3421634..227199413c 100644 --- a/pkgs/racket-doc/scribblings/reference/hashes.scrbl +++ b/pkgs/racket-doc/scribblings/reference/hashes.scrbl @@ -170,7 +170,14 @@ See also @racket[make-custom-hash].} Like @racket[make-hash], @racket[make-hasheq], and @racket[make-hasheqv], but creates a mutable hash table that holds -keys weakly.} +keys weakly. + +Beware that values in the table are retained normally. If a value in +the table refers back to its key, then the table will retain the value +and therefore the key; the mapping will never be removed from the +table even if the key becomes otherwise inaccessible. To avoid that +problem, instead of mapping the key to the value, map the key to an +@tech{ephemeron} that pairs the key and value.} @deftogether[( @defproc[(make-immutable-hash [assocs (listof pair?) null]) From a41c63be098943a26467446e859e53db7f07aef0 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 23 Oct 2015 16:13:57 -0400 Subject: [PATCH 358/381] call SCHEME_EXPAND_OBSERVE_* only when in expand mode, not compile Merge to 6.3. --- racket/src/racket/src/compile.c | 191 ++++++++++++++++++++++---------- racket/src/racket/src/module.c | 161 +++++++++++++++++++-------- 2 files changed, 248 insertions(+), 104 deletions(-) diff --git a/racket/src/racket/src/compile.c b/racket/src/racket/src/compile.c index 2e1bec2e0c..08411a061b 100644 --- a/racket/src/racket/src/compile.c +++ b/racket/src/racket/src/compile.c @@ -2824,7 +2824,9 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ body = scheme_datum_to_syntax(body, form, form, 0, 0); if (scope) body = scheme_stx_add_scope(body, scope, scheme_env_phase(env->genv)); - SCHEME_EXPAND_OBSERVE_LET_RENAMES(env->observer, vars, body); + if (!erec[drec].comp) { + SCHEME_EXPAND_OBSERVE_LET_RENAMES(env->observer, vars, body); + } /* Pass 2: Expand */ @@ -2833,7 +2835,9 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ while (SCHEME_STX_PAIRP(vars)) { Scheme_Object *rhs, *rhs_name; - SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + if (!erec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + } v = SCHEME_STX_CAR(vars); @@ -2897,7 +2901,9 @@ do_let_expand(Scheme_Object *orig_form, Scheme_Comp_Env *origenv, Scheme_Expand_ first = scheme_datum_to_syntax(first, vs, vs, 0, 1); } - SCHEME_EXPAND_OBSERVE_NEXT_GROUP(env->observer); + if (!erec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT_GROUP(env->observer); + } scheme_init_expand_recs(erec, drec, &erec1, 1); env->value_name = boundname; if (!body_block) @@ -3217,8 +3223,10 @@ do_begin_expand(char *name, if (SCHEME_STX_NULLP(rest)) { if (!zero && scheme_is_toplevel(env)) { - SCHEME_EXPAND_OBSERVE_ENTER_LIST(env->observer, form); - SCHEME_EXPAND_OBSERVE_EXIT_LIST(env->observer, form); + if (!erec[drec].comp) { + SCHEME_EXPAND_OBSERVE_ENTER_LIST(env->observer, form); + SCHEME_EXPAND_OBSERVE_EXIT_LIST(env->observer, form); + } return orig_form; } scheme_wrong_syntax(NULL, NULL, form, "empty form not allowed"); @@ -3238,12 +3246,16 @@ do_begin_expand(char *name, fst = SCHEME_STX_CAR(rest); rest = SCHEME_STX_CDR(rest); - SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + if (!erec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + } env->value_name = boundname; fst = scheme_expand_expr(fst, env, &erec1, 0); env->value_name = NULL; rest = scheme_datum_to_syntax(rest, form, form, 0, 0); - SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + if (!erec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + } rest = expand_list(rest, env, erec, drec); form = cons(fst, rest); @@ -3589,7 +3601,9 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem Scheme_Object *form, *l, *fn, *vec, *dummy; Scheme_Comp_Env *env; - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN_FOR_SYNTAX(in_env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN_FOR_SYNTAX(in_env->observer); + } form = orig_form; @@ -3598,7 +3612,9 @@ begin_for_syntax_expand(Scheme_Object *orig_form, Scheme_Comp_Env *in_env, Schem (void)check_form(form, form); - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(in_env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(in_env->observer); + } scheme_prepare_exp_env(in_env->genv); scheme_prepare_compile_env(in_env->genv->exp_env); @@ -3836,7 +3852,9 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object but it's not likely that a let-syntax-bound macro is going to run lots of times, so JITting is probably not worth it. */ - SCHEME_EXPAND_OBSERVE_NEXT(eenv->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(eenv->observer); + } a_expr = a; a = eval_letmacro_rhs(a_expr, rhs_env, @@ -3903,7 +3921,9 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object scheme_merge_undefineds(eenv, rhs_env); - SCHEME_EXPAND_OBSERVE_EXIT_BIND(observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_EXIT_BIND(observer); + } } static Scheme_Object * @@ -4086,9 +4106,10 @@ do_letrec_syntaxes(const char *where, } } - SCHEME_EXPAND_OBSERVE_LETREC_SYNTAXES_RENAMES(stx_env->observer, bindings, var_bindings, body); - - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(stx_env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_LETREC_SYNTAXES_RENAMES(stx_env->observer, bindings, var_bindings, body); + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(stx_env->observer); + } scheme_prepare_exp_env(stx_env->genv); scheme_prepare_compile_env(stx_env->genv->exp_env); @@ -4098,7 +4119,9 @@ do_letrec_syntaxes(const char *where, for (v = bindings; SCHEME_STX_PAIRP(v); v = SCHEME_STX_CDR(v)) { Scheme_Object *a, *names; - SCHEME_EXPAND_OBSERVE_NEXT(stx_env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(stx_env->observer); + } a = SCHEME_STX_CAR(v); names = SCHEME_STX_CAR(a); @@ -4114,7 +4137,9 @@ do_letrec_syntaxes(const char *where, } } - SCHEME_EXPAND_OBSERVE_NEXT_GROUP(stx_env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT_GROUP(stx_env->observer); + } if (!env_already && names_to_disappear) { /* Need to add renaming for disappeared bindings. If they @@ -4177,7 +4202,7 @@ do_letrec_syntaxes(const char *where, v = scheme_stx_taint_rearm(v, orig_forms); if (!restore) { - SCHEME_EXPAND_OBSERVE_TAG(stx_env->observer,v); + SCHEME_EXPAND_OBSERVE_TAG(stx_env->observer,v); /* in "expand" branch */ } } var_env->value_name = NULL; @@ -4201,7 +4226,7 @@ do_letrec_syntaxes(const char *where, rec[drec].env_already = 1; } - SCHEME_EXPAND_OBSERVE_PRIM_LETREC_VALUES(stx_env->observer); + SCHEME_EXPAND_OBSERVE_PRIM_LETREC_VALUES(stx_env->observer); /* in "expand" branch */ v = do_let_expand(v, stx_env, rec, drec, "letrec-values", 1, 1, var_env); if (restore) { @@ -4213,7 +4238,7 @@ do_letrec_syntaxes(const char *where, v = cons(formname, cons(bindings, v)); v = scheme_datum_to_syntax(v, orig_forms, scheme_sys_wraps(origenv), 0, 2); } else { - SCHEME_EXPAND_OBSERVE_TAG(stx_env->observer,v); + SCHEME_EXPAND_OBSERVE_TAG(stx_env->observer,v); /* in "expand" branch */ } } } @@ -4586,7 +4611,9 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, Scheme_Expand_Info erec1; Scheme_Env *menv = NULL; - SCHEME_EXPAND_OBSERVE_ENTER_CHECK(env->observer, first); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_ENTER_CHECK(env->observer, first); + } while (1) { *current_val = NULL; @@ -4599,7 +4626,9 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, } if (!SCHEME_STX_SYMBOLP(name)) { - SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); + } return first; } @@ -4627,7 +4656,9 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, if (!val) { first = install_alt_from_rename(first, alt_first); - SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); + } return first; } else if (SAME_TYPE(SCHEME_TYPE(val), scheme_macro_type)) { if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(val), @@ -4661,7 +4692,9 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first, } } else { first = install_alt_from_rename(first, alt_first); - SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_EXIT_CHECK(env->observer, first); + } return first; } } @@ -4775,7 +4808,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, if (rec[drec].comp) { scheme_default_compile_rec(rec, drec); } else { - SCHEME_EXPAND_OBSERVE_VISIT(env->observer,form); + SCHEME_EXPAND_OBSERVE_VISIT(env->observer,form); /* in "expand" branch */ } if (SAME_TYPE(SCHEME_TYPE(SCHEME_STX_VAL(form)), scheme_expanded_syntax_type)) { @@ -4832,7 +4865,9 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, &bind_id, &need_macro_scope, &inline_variant); - SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer,find_name); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer,find_name); + } if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { @@ -4867,10 +4902,12 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } else { if (SAME_TYPE(SCHEME_TYPE(var), scheme_syntax_compiler_type)) { if (var == stop_expander) { - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer,form); - SCHEME_EXPAND_OBSERVE_PRIM_STOP(env->observer); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer,form); - SCHEME_EXPAND_OBSERVE_RETURN(env->observer,form); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer,form); + SCHEME_EXPAND_OBSERVE_PRIM_STOP(env->observer); + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer,form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer,form); + } return form; } else { scheme_wrong_syntax(NULL, NULL, form, "bad syntax"); @@ -4904,14 +4941,14 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, else return var; } else { - SCHEME_EXPAND_OBSERVE_VARIABLE(env->observer, form, find_name); + SCHEME_EXPAND_OBSERVE_VARIABLE(env->observer, form, find_name); /* in "expand" branch */ if (bind_id && rec[drec].substitute_bindings) find_name = bind_id; if (protected) { /* Add a property to indicate that the name is protected */ find_name = scheme_stx_property(find_name, protected_symbol, scheme_true); } - SCHEME_EXPAND_OBSERVE_RETURN(env->observer, find_name); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, find_name); /* in "expand" branch */ return find_name; /* which is usually == form */ } } @@ -4960,7 +4997,9 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, NULL, &need_macro_scope, NULL); - SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer, find_name); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer, find_name); + } if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), @@ -5057,7 +5096,9 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, NULL, &need_macro_scope, NULL); - SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer, find_name); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_RESOLVE(env->observer, find_name); + } if (var && SAME_TYPE(SCHEME_TYPE(var), scheme_macro_type) && scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) { @@ -5088,10 +5129,12 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, || SAME_TYPE(SCHEME_TYPE(var), scheme_syntax_compiler_type))) { if (SAME_OBJ(var, stop_expander)) { /* Return original: */ - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, form); - SCHEME_EXPAND_OBSERVE_PRIM_STOP(env->observer); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer, form); - SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, form); + SCHEME_EXPAND_OBSERVE_PRIM_STOP(env->observer); + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer, form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); + } return form; } else if (rec[drec].comp && SAME_OBJ(var, normal) && !env->observer) { /* Skip creation of intermediate form */ @@ -5112,7 +5155,9 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } else { name = scheme_stx_taint_disarm(form, NULL); form = scheme_datum_to_syntax(scheme_make_pair(stx, name), form, form, 0, 2); - SCHEME_EXPAND_OBSERVE_TAG(env->observer, form); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_TAG(env->observer, form); + } } if (SAME_TYPE(SCHEME_TYPE(var), scheme_syntax_compiler_type)) { @@ -5123,7 +5168,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } else { Scheme_Syntax_Expander *f; f = (Scheme_Syntax_Expander *)SCHEME_SYNTAX_EXP(var); - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, form); + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, form); /* in "expand" branch */ form = f(form, env, rec, drec); SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer, form); SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); @@ -5175,7 +5220,9 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, return form; /* We've gone as deep as requested */ } - SCHEME_EXPAND_OBSERVE_ENTER_MACRO(env->observer, form); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_ENTER_MACRO(env->observer, form); + } if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var), scheme_frame_to_expansion_context_symbol(env->flags))) { form = compile_expand_macro_app(name, menv, var, form, env, rec, drec, need_macro_scope); @@ -5187,7 +5234,9 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, } } else form = adjust_for_other_context(form, var, env); - SCHEME_EXPAND_OBSERVE_EXIT_MACRO(env->observer, form); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_EXIT_MACRO(env->observer, form); + } if (rec[drec].comp) goto top; @@ -5197,7 +5246,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, if (rec[drec].depth) goto top; else { - SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); + SCHEME_EXPAND_OBSERVE_RETURN(env->observer, form); /* in "expand" branch */ return form; } } @@ -5826,7 +5875,9 @@ compile_expand_expr_lift_to_let(Scheme_Object *form, Scheme_Comp_Env *env, } else o = form; form = scheme_add_lifts_as_let(o, l, env, orig_form, rec[drec].comp); - SCHEME_EXPAND_OBSERVE_LETLIFT_LOOP(env->observer, form); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_LETLIFT_LOOP(env->observer, form); + } form = compile_expand_expr_lift_to_let(form, env, recs, 1); if (rec[drec].comp) scheme_merge_compile_recs(rec, drec, recs, 2); @@ -5927,11 +5978,15 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, old = forms; forms = add_scope_at_arbitrary_phase(forms, rib); - SCHEME_EXPAND_OBSERVE_BLOCK_RENAMES(env->observer, forms, old); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_BLOCK_RENAMES(env->observer, forms, old); + } try_again: - SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + } if (!SCHEME_STX_PAIRP(forms)) { scheme_wrong_syntax(scheme_begin_stx_string, NULL, beginify(env, forms), "bad syntax"); @@ -5961,7 +6016,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, /* Inline content */ Scheme_Object *orig_forms = forms; - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(env->observer); + } /* FIXME: Redundant with check done by scheme_flatten_begin below? */ if (scheme_stx_proper_list_length(first) < 0) @@ -5981,7 +6038,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, forms = scheme_flatten_begin(first, forms); - SCHEME_EXPAND_OBSERVE_SPLICE(env->observer, forms); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_SPLICE(env->observer, forms); + } if (SCHEME_STX_NULLP(forms)) { if (!SCHEME_PAIRP(pre_exprs)) { @@ -6047,10 +6106,12 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, v = SCHEME_STX_CDR(first); - if (is_val) { - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(env->observer); - } else { - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(env->observer); + if (!rec[drec].comp) { + if (is_val) { + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(env->observer); + } else { + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(env->observer); + } } if (!SCHEME_STX_PAIRP(v)) @@ -6080,7 +6141,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, var = SCHEME_STX_CAR(first); v = scheme_stx_track(v, first, var); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer,v); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer,v); + } link = scheme_make_pair(v, scheme_null); if (is_val) { @@ -6146,7 +6209,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (!is_val) { /* Evaluate and bind syntaxes */ - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); + } scheme_prepare_exp_env(new_env->genv); scheme_prepare_compile_env(new_env->genv->exp_env); pos = 0; @@ -6169,7 +6234,9 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (!SCHEME_STX_NULLP(result)) { first = SCHEME_STX_CAR(result); first = scheme_datum_to_syntax(first, forms, forms, 0, 0); - SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(env->observer); + } is_last = SCHEME_STX_NULLP(SCHEME_STX_CDR(result)); if (is_last) env->value_name = orig_vname; @@ -6182,9 +6249,13 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (SAME_OBJ(gval, scheme_begin_syntax)) { /* Inline content */ result = SCHEME_STX_CDR(result); - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN(env->observer); + } result = scheme_flatten_begin(first, result); - SCHEME_EXPAND_OBSERVE_SPLICE(env->observer,result); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_SPLICE(env->observer,result); + } goto define_try_again; } else if (mixed) { /* accumulate expr for either sequence after definitions @@ -6263,8 +6334,10 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, if (rec[drec].depth > 0) --rec[drec].depth; if (rec[drec].depth) { - SCHEME_EXPAND_OBSERVE_BLOCK_TO_LETREC(env->observer, - scheme_make_pair(result, scheme_null)); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_BLOCK_TO_LETREC(env->observer, + scheme_make_pair(result, scheme_null)); + } env = scheme_no_defines(env); env->value_name = orig_vname; result = scheme_expand_expr(result, env, rec, drec); @@ -6330,7 +6403,7 @@ compile_expand_block(Scheme_Object *forms, Scheme_Comp_Env *env, env->value_name = orig_vname; - SCHEME_EXPAND_OBSERVE_BLOCK_TO_LIST(env->observer, forms); + SCHEME_EXPAND_OBSERVE_BLOCK_TO_LIST(env->observer, forms); /* in "expand" branch */ forms = expand_list(forms, env, recs, 0); return forms; } diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 4cf6cedf0a..ccb262cab2 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -7205,7 +7205,9 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, m->super_bxs_info = super_bxs_info; } - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(env->observer); + } /* load the module for the initial require */ if (iidx) { @@ -7308,8 +7310,10 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_datum_to_syntax(fm, form, mb_ctx, 0, 2); - if (check_mb) { - SCHEME_EXPAND_OBSERVE_TAG(env->observer, fm); + if (!rec[drec].comp) { + if (check_mb) { + SCHEME_EXPAND_OBSERVE_TAG(env->observer, fm); + } } fm = scheme_stx_property(fm, module_name_symbol, scheme_resolved_module_path_value(rmp)); @@ -7322,7 +7326,9 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_stx_add_module_frame_context(fm, rn_set); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer, fm); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer, fm); + } if (!check_mb) { fm = scheme_check_immediate_macro(fm, benv, rec, drec, &mbval, 1); @@ -7334,8 +7340,10 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, fm = scheme_make_pair(mb, scheme_make_pair(fm, scheme_null)); fm = scheme_datum_to_syntax(fm, form, mb_ctx, 0, 2); fm = scheme_stx_property(fm, module_name_symbol, scheme_resolved_module_path_value(rmp)); - - SCHEME_EXPAND_OBSERVE_TAG(env->observer, fm); + + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_TAG(env->observer, fm); + } check_mb = 1; } @@ -7452,7 +7460,9 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, LOG_END_EXPAND(m); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer, fm); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_RENAME_ONE(env->observer, fm); + } return fm; } @@ -8182,7 +8192,9 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env form = introduce_to_module_context(form, rn_set); observer = env->observer; - SCHEME_EXPAND_OBSERVE_RENAME_ONE(observer, form); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_RENAME_ONE(observer, form); + } _num_phases = MALLOC_ONE_ATOMIC(int); *_num_phases = 0; @@ -8434,7 +8446,9 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env env->genv->module->dummy = dummy; } - SCHEME_EXPAND_OBSERVE_NEXT(observer); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_NEXT(observer); + } /* Submodules */ if (has_submodules) { @@ -8582,11 +8596,13 @@ static Scheme_Object *handle_submodule_form(const char *who, e = revert_use_site_scopes_via_context(e, rn_set, phase); - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); - if (is_star) { - SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE_STAR(observer); - } else { - SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); + if (is_star) { + SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE_STAR(observer); + } else { + SCHEME_EXPAND_OBSERVE_PRIM_SUBMODULE(observer); + } } if (SCHEME_STX_PAIRP(e)) { @@ -8632,7 +8648,9 @@ static Scheme_Object *handle_submodule_form(const char *who, *_kind = MODULE_MODFORM_KIND; } - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer,e); + if (erec) { + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer,e); + } return e; } @@ -8838,7 +8856,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ while (1) { Scheme_Object *fst; - SCHEME_EXPAND_OBSERVE_NEXT(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_NEXT(observer); + } e = SCHEME_STX_CAR(fm); @@ -8882,9 +8902,13 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ e = introduce_to_module_context(e, rn_set); fm = scheme_named_map_1(NULL, introduce_to_module_context, fm, rn_set); fm = scheme_make_pair(e, fm); - SCHEME_EXPAND_OBSERVE_RENAME_LIST(observer, fm); + if (erec) { + SCHEME_EXPAND_OBSERVE_RENAME_LIST(observer, fm); + } fm = scheme_append(fst, fm); - SCHEME_EXPAND_OBSERVE_MODULE_LIFT_LOOP(observer, fst); + if (erec) { + SCHEME_EXPAND_OBSERVE_MODULE_LIFT_LOOP(observer, fst); + } } else { /* No definition lifts added... */ if (SCHEME_STX_PAIRP(e)) @@ -8895,9 +8919,13 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ if (fst && SCHEME_STX_SYMBOLP(fst) && scheme_stx_free_eq_x(scheme_begin_stx, fst, phase)) { fm = SCHEME_STX_CDR(fm); e = introduce_to_module_context(e, rn_set); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(observer, e); + if (erec) { + SCHEME_EXPAND_OBSERVE_RENAME_ONE(observer, e); + } fm = scheme_flatten_begin(e, fm); - SCHEME_EXPAND_OBSERVE_SPLICE(observer, fm); + if (erec) { + SCHEME_EXPAND_OBSERVE_SPLICE(observer, fm); + } if (SCHEME_STX_NULLP(fm)) { e = scheme_frame_get_provide_lifts(xenv); e = scheme_reverse(e); @@ -8911,7 +8939,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ fm = e; if (SCHEME_NULLP(fm) && expand_ends) fm = get_higher_phase_lifts(bxs, begin_for_syntax_stx); - SCHEME_EXPAND_OBSERVE_MODULE_LIFT_END_LOOP(observer, fm); + if (erec) { + SCHEME_EXPAND_OBSERVE_MODULE_LIFT_END_LOOP(observer, fm); + } if (SCHEME_NULLP(fm)) { e = NULL; break; @@ -8925,7 +8955,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ e = introduce_to_module_context(e, rn_set); - SCHEME_EXPAND_OBSERVE_RENAME_ONE(observer, e); + if (erec) { + SCHEME_EXPAND_OBSERVE_RENAME_ONE(observer, e); + } if (SCHEME_STX_PAIRP(e)) { Scheme_Object *fst; @@ -8938,8 +8970,10 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ Scheme_Object *vars, *val; int var_count = 0; - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_VALUES(observer); + } /* Create top-level vars; uses revert_use_site_scopes() on the vars */ scheme_define_parse(e, &vars, &val, 0, xenv, 1); @@ -8995,7 +9029,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ e, e, 0, 2); } - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + if (erec) { + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + } kind = DEFN_MODFORM_KIND; } else if (scheme_stx_free_eq_x(scheme_define_syntaxes_stx, fst, phase) || scheme_stx_free_eq_x(scheme_begin_for_syntax_stx, fst, phase)) { @@ -9013,15 +9049,21 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ for_stx = scheme_stx_free_eq_x(scheme_begin_for_syntax_stx, fst, phase); - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); + if (erec) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); + } if (for_stx) { - SCHEME_EXPAND_OBSERVE_PRIM_BEGIN_FOR_SYNTAX(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_PRIM_BEGIN_FOR_SYNTAX(observer); + } if (scheme_stx_proper_list_length(e) < 0) scheme_wrong_syntax(NULL, NULL, e, NULL); code = e; } else { - SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_PRIM_DEFINE_SYNTAXES(observer); + } scheme_define_parse(e, &names, &code, 1, env, 1); } @@ -9030,7 +9072,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ else boundname = scheme_false; - SCHEME_EXPAND_OBSERVE_PREPARE_ENV(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_PREPARE_ENV(observer); + } scheme_prepare_exp_env(env->genv); scheme_prepare_compile_env(env->genv->exp_env); @@ -9040,6 +9084,7 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ eenv = scheme_new_comp_env(env->genv->exp_env, env->insp, frame_scopes, SCHEME_KEEP_SCOPES_FRAME); + eenv->observer = observer; if (!for_stx) scheme_frame_captures_lifts(eenv, NULL, NULL, scheme_false, scheme_false, req_data, scheme_false, scheme_false); @@ -9213,7 +9258,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ } else e = NULL; - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + if (erec) { + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + } kind = DONE_MODFORM_KIND; @@ -9222,8 +9269,10 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ non_phaseless_form = e; } else if (scheme_stx_free_eq_x(require_stx, fst, phase)) { /************ require *************/ - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); - SCHEME_EXPAND_OBSERVE_PRIM_REQUIRE(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); + SCHEME_EXPAND_OBSERVE_PRIM_REQUIRE(observer); + } e = revert_use_site_scopes_via_context(e, rn_set, phase); @@ -9241,7 +9290,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ if (!erec) e = NULL; - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + if (erec) { + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + } kind = DONE_MODFORM_KIND; } else if (scheme_stx_free_eq_x(provide_stx, fst, phase)) { /************ provide *************/ @@ -9334,7 +9385,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ fm = get_higher_phase_lifts(bxs, begin_for_syntax_stx); } else fm = e; - SCHEME_EXPAND_OBSERVE_MODULE_LIFT_END_LOOP(observer, fm); + if (erec) { + SCHEME_EXPAND_OBSERVE_MODULE_LIFT_END_LOOP(observer, fm); + } } } /* first = a list of (cons semi-expanded-expression kind) */ @@ -9351,7 +9404,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ } /* Pass 2 */ - SCHEME_EXPAND_OBSERVE_NEXT_GROUP(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_NEXT_GROUP(observer); + } { /* Module and each `begin-for-syntax' group manages its own prefix: */ @@ -9379,7 +9434,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ kind = SCHEME_INT_VAL(SCHEME_CDR(e)); e = SCHEME_CAR(e); - SCHEME_EXPAND_OBSERVE_NEXT(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_NEXT(observer); + } if (kind == SAVED_MODFORM_KIND) { expanded_l = scheme_make_pair(SCHEME_CDR(e), expanded_l); @@ -9453,7 +9510,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ /* Lifts - insert them and try again */ Scheme_Object *fst; *bxs->all_simple_bindings = 0; - SCHEME_EXPAND_OBSERVE_MODULE_LIFT_LOOP(observer, scheme_copy_list(l)); + if (erec) { + SCHEME_EXPAND_OBSERVE_MODULE_LIFT_LOOP(observer, scheme_copy_list(l)); + } if (erec) { e = scheme_make_pair(scheme_make_pair(e, SCHEME_CAR(expanded_l)), scheme_make_integer(SAVED_MODFORM_KIND)); /* kept both expanded & maybe compiled */ @@ -9519,7 +9578,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ p = e; expr_cnt = 0; } - SCHEME_EXPAND_OBSERVE_MODULE_LIFT_END_LOOP(observer, p); + if (erec) { + SCHEME_EXPAND_OBSERVE_MODULE_LIFT_END_LOOP(observer, p); + } for (ll = p; SCHEME_PAIRP(ll); ll = SCHEME_CDR(ll)) { e = SCHEME_CAR(ll); if (expr_cnt <= 0) { @@ -9558,7 +9619,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ /* Pass 3 */ /* if at phase 0, expand provides for all phases */ - SCHEME_EXPAND_OBSERVE_NEXT_GROUP(observer); + if (erec) { + SCHEME_EXPAND_OBSERVE_NEXT_GROUP(observer); + } if (phase == 0) { Scheme_Object *expanded_provides; @@ -9660,9 +9723,11 @@ static Scheme_Object *expand_all_provides(Scheme_Object *form, /* Expand and add provides to table: */ - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); - SCHEME_EXPAND_OBSERVE_PRIM_PROVIDE(observer); - + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(observer, e); + SCHEME_EXPAND_OBSERVE_PRIM_PROVIDE(observer); + } + ex = e; if (provide_phase != 0) { @@ -9692,7 +9757,9 @@ static Scheme_Object *expand_all_provides(Scheme_Object *form, if (keep_expanded) expanded_provides = scheme_make_pair(ex, expanded_provides); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(observer, e); + } saved_provides = SCHEME_CDR(saved_provides); } @@ -9720,10 +9787,14 @@ static Scheme_Object *expand_submodules(Scheme_Compile_Expand_Info *rec, int dre while (!SCHEME_NULLP(l)) { mod = SCHEME_CAR(l); - SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, SCHEME_CAR(mod)); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_ENTER_PRIM(env->observer, SCHEME_CAR(mod)); + } mod = do_module(SCHEME_CAR(mod), env, rec, drec, ancestry, env->genv->module->submodule_path, post, bxs, SCHEME_CDR(mod)); - SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer,mod); + if (!rec[drec].comp) { + SCHEME_EXPAND_OBSERVE_EXIT_PRIM(env->observer,mod); + } mods = scheme_make_pair(mod, mods); From 3eb2c20ad026706fa3f16eea0c11ac2874ce44fc Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 23 Oct 2015 15:36:57 -0600 Subject: [PATCH 359/381] avoid excessive memory use in `or` expansion When `or` has many subexpressions, the expansion generates a sequence of deeply nested `let`s, where original and macro-introduced forms are interleaved in a way that defeats a minimal child-is-same-as-parent sharing of scope sets. Add a small cache that's good enough to capture extra sharing and dramatically lower memory use for an `or` that has 1000 subexpressions. --- pkgs/racket-test/tests/racket/stress/or.rkt | 34 ++++++++++++ racket/src/racket/include/schthread.h | 7 +++ racket/src/racket/src/syntax.c | 59 ++++++++++++++++++--- 3 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 pkgs/racket-test/tests/racket/stress/or.rkt diff --git a/pkgs/racket-test/tests/racket/stress/or.rkt b/pkgs/racket-test/tests/racket/stress/or.rkt new file mode 100644 index 0000000000..bb851d156f --- /dev/null +++ b/pkgs/racket-test/tests/racket/stress/or.rkt @@ -0,0 +1,34 @@ +#lang racket/base + +;; Ensure that `or` with lots of arguments doesn't +;; use excessive memory to expand --- which can happen +;; if there's not enough sharing of scope sets, for +;; example. + +(define ns (make-base-namespace)) + +(define c (make-custodian)) +(custodian-limit-memory c (* 500 1024 1024)) + +(define done? #f) + +(thread-wait + (parameterize ([current-namespace ns] + [current-custodian c]) + (thread + (lambda () + (namespace-require '(for-syntax racket/base)) + (eval + '(define-syntax (m stx) + (syntax-case stx () + [(_ id) + #`(define (id x) + (or #,@(for/list ([i 1000]) + #`(= x #,i))))]))) + (eval '(m f)) + (set! done? #t))))) + +(unless done? + (error "failed")) + + diff --git a/racket/src/racket/include/schthread.h b/racket/src/racket/include/schthread.h index 2ff040cc54..e614cf1842 100644 --- a/racket/src/racket/include/schthread.h +++ b/racket/src/racket/include/schthread.h @@ -96,6 +96,9 @@ MZ_EXTERN void scheme_init_os_thread(void); #define STACK_CACHE_SIZE 32 #define NUM_MORE_CONSTANT_STXES 24 + /* The number of cached scope sets should be a power of 2: */ +#define NUM_RECENT_SCOPE_SETS 8 + /* This structure must be 4 words: */ typedef struct { void *orig_return_address; @@ -243,6 +246,8 @@ typedef struct Thread_Local_Variables { struct Binding_Cache_Entry *binding_cache_table_; intptr_t binding_cache_pos_; intptr_t binding_cache_len_; + struct Scheme_Scope_Set *recent_scope_sets_[2][NUM_RECENT_SCOPE_SETS]; + int recent_scope_sets_pos_[2]; struct Scheme_Thread *scheme_current_thread_; struct Scheme_Thread *scheme_main_thread_; struct Scheme_Thread *scheme_first_thread_; @@ -636,6 +641,8 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL; #define binding_cache_table XOA (scheme_get_thread_local_variables()->binding_cache_table_) #define binding_cache_pos XOA (scheme_get_thread_local_variables()->binding_cache_pos_) #define binding_cache_len XOA (scheme_get_thread_local_variables()->binding_cache_len_) +#define recent_scope_sets XOA (scheme_get_thread_local_variables()->recent_scope_sets_) +#define recent_scope_sets_pos XOA (scheme_get_thread_local_variables()->recent_scope_sets_pos_) #define scheme_current_thread XOA (scheme_get_thread_local_variables()->scheme_current_thread_) #define scheme_main_thread XOA (scheme_get_thread_local_variables()->scheme_main_thread_) #define scheme_first_thread XOA (scheme_get_thread_local_variables()->scheme_first_thread_) diff --git a/racket/src/racket/src/syntax.c b/racket/src/racket/src/syntax.c index bcc5f263f4..62c5a8b0cb 100644 --- a/racket/src/racket/src/syntax.c +++ b/racket/src/racket/src/syntax.c @@ -101,6 +101,8 @@ THREAD_LOCAL_DECL(static Scheme_Bucket_Table *taint_intern_table); THREAD_LOCAL_DECL(static struct Binding_Cache_Entry *binding_cache_table); THREAD_LOCAL_DECL(static intptr_t binding_cache_pos); THREAD_LOCAL_DECL(static intptr_t binding_cache_len); +THREAD_LOCAL_DECL(static Scheme_Scope_Set *recent_scope_sets[2][NUM_RECENT_SCOPE_SETS]); +THREAD_LOCAL_DECL(static int recent_scope_sets_pos[2]); static Scheme_Object *syntax_p(int argc, Scheme_Object **argv); @@ -1677,6 +1679,13 @@ Scheme_Object *scheme_make_shift(Scheme_Object *phase_delta, void scheme_clear_shift_cache(void) { + int i; + + for (i = 0; i < NUM_RECENT_SCOPE_SETS; i++) { + recent_scope_sets[0][i] = NULL; + recent_scope_sets[1][i] = NULL; + } + last_phase_shift = NULL; nominal_ipair_cache = NULL; clear_binding_cache(); @@ -1782,6 +1791,35 @@ int stx_shorts, stx_meds, stx_longs, stx_couldas; # define COUNT_PROPAGATES(x) /* empty */ #endif +static void intern_scope_set(Scheme_Scope_Table *t, int prop_table) +/* We don't realy intern, but approximate interning by checking + against a small set of recently allocated scope sets. That's good + enough to find sharing for a deeply nested sequence of `let`s from + a many-argument `or`, for example, where the interleaving of + original an macro-introduced syntax prevents the usual + child-is-same-as-parent sharing detecting from working well + enough. */ +{ + int i; + + if (!t->simple_scopes || !scope_set_count(t->simple_scopes)) + return; + + for (i = 0; i < NUM_RECENT_SCOPE_SETS; i++) { + if (recent_scope_sets[prop_table][i]) { + if (recent_scope_sets[prop_table][i] == t->simple_scopes) + return; + if (scopes_equal(recent_scope_sets[prop_table][i], t->simple_scopes)) { + t->simple_scopes = recent_scope_sets[prop_table][i]; + } + } + } + + recent_scope_sets[prop_table][recent_scope_sets_pos[prop_table]] = t->simple_scopes; + + recent_scope_sets_pos[prop_table] = ((recent_scope_sets_pos[prop_table] + 1) & (NUM_RECENT_SCOPE_SETS - 1)); +} + static Scheme_Object *propagate_scope_set(Scheme_Scope_Set *props, Scheme_Object *o, Scheme_Object *phase, int flag, GC_CAN_IGNORE int *mutate) @@ -1790,15 +1828,22 @@ static Scheme_Object *propagate_scope_set(Scheme_Scope_Set *props, Scheme_Object Scheme_Object *key, *val; i = scope_set_next(props, -1); - while (i != -1) { - scope_set_index(props, i, &key, &val); + if (i != -1) { + do { + scope_set_index(props, i, &key, &val); - STX_ASSERT(!SCHEME_SCOPE_HAS_OWNER((Scheme_Scope *)key)); + STX_ASSERT(!SCHEME_SCOPE_HAS_OWNER((Scheme_Scope *)key)); - o = stx_adjust_scope(o, key, phase, SCHEME_INT_VAL(val) | flag, mutate); - - i = scope_set_next(props, i); - } + o = stx_adjust_scope(o, key, phase, SCHEME_INT_VAL(val) | flag, mutate); + + i = scope_set_next(props, i); + } while (i != -1); + + intern_scope_set(((Scheme_Stx *)o)->scopes, 0); + if (STX_KEY(((Scheme_Stx *)o)) & STX_SUBSTX_FLAG + && ((Scheme_Stx *)o)->u.to_propagate) + intern_scope_set(((Scheme_Stx *)o)->u.to_propagate, 1); + } return o; } From c0209b1d80e9ef1b4603f51279a134783d1a1039 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 24 Oct 2015 14:13:51 -0500 Subject: [PATCH 360/381] preserve originalness so that arrows in define/contract work properly with check syntax Thanks to Matthew for the fix Please include in 6.3 --- racket/collects/racket/contract/region.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/collects/racket/contract/region.rkt b/racket/collects/racket/contract/region.rkt index ac92a82878..c93643074a 100644 --- a/racket/collects/racket/contract/region.rkt +++ b/racket/collects/racket/contract/region.rkt @@ -679,7 +679,7 @@ [(free-vars free-ctcs) (values (syntax->list #'(fv.var ...)) (syntax->list #'(fv.ctc ...)))]) - (define add-context (make-syntax-introducer)) + (define add-context (make-syntax-introducer #t)) (with-syntax ([blame-stx #''(region blame)] [blame-id (generate-temporary)] [(res ...) (generate-temporaries #'(rc.ctc ...))] @@ -733,7 +733,7 @@ [(protected protections) (values (syntax->list #'(ec.var ...)) (syntax->list #'(ec.ctc ...)))]) - (define add-context (make-syntax-introducer)) + (define add-context (make-syntax-introducer #t)) (with-syntax ([blame-stx #''(region blame)] [blame-id (generate-temporary)] [(free-var ...) free-vars] From 67e3899272792c2e510abdf39865b3a40dfd8a8d Mon Sep 17 00:00:00 2001 From: Alex Knauth Date: Fri, 23 Oct 2015 17:24:53 -0400 Subject: [PATCH 361/381] Allow separate read and write contracts for box/c --- .../scribblings/reference/contracts.scrbl | 8 +- .../racket-test/tests/racket/contract/box.rkt | 29 +++++ .../collects/racket/contract/private/box.rkt | 102 ++++++++++-------- 3 files changed, 91 insertions(+), 48 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index 6360ea9e34..d22ffc44cc 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -363,14 +363,16 @@ Returns the same contract as @racket[(vector/c c ... #:immutable #t)]. This form reasons of backwards compatibility.} -@defproc[(box/c [c contract?] +@defproc[(box/c [in-c contract?] + [c contract? in-c] [#:immutable immutable (or/c #t #f 'dont-care) 'dont-care] [#:flat? flat? boolean? #f]) contract?]{ -Returns a contract that recognizes boxes. The content of the box must match @racket[c]. +Returns a contract that recognizes boxes. The content of the box must match @racket[c], +and mutations on mutable boxes must match @racket[in-c]. If the @racket[flat?] argument is @racket[#t], then the resulting contract is -a flat contract, and the @racket[c] argument must also be a flat contract. Such +a flat contract, and the @racket[out] argument must also be a flat contract. Such flat contracts will be unsound if applied to mutable boxes, as they will not check future operations on the box. diff --git a/pkgs/racket-test/tests/racket/contract/box.rkt b/pkgs/racket-test/tests/racket/contract/box.rkt index 083c8f2438..4538f25f34 100644 --- a/pkgs/racket-test/tests/racket/contract/box.rkt +++ b/pkgs/racket-test/tests/racket/contract/box.rkt @@ -6,6 +6,18 @@ (λ (box v) v) (λ (box v) v))]) (contract (box/c any/c) v 'pos 'neg))) + + (test/no-error + '(let ([v (chaperone-box (box-immutable 1) + (λ (box v) v) + (λ (box v) v))]) + (contract (box/c none/c any/c) v 'pos 'neg))) + + (test/no-error + '(let ([v (chaperone-box (box 1) + (λ (box v) v) + (λ (box v) v))]) + (set-box! (contract (box/c boolean? none/c) v 'pos 'neg) #t))) (test/pos-blame 'box/c1 @@ -30,10 +42,18 @@ (test/neg-blame 'box/c6 '(set-box! (contract (box/c boolean?) (box #f) 'pos 'neg) 11)) + + (test/neg-blame + 'box/c6 + '(set-box! (contract (box/c boolean? any/c) (box #f) 'pos 'neg) 11)) (test/neg-blame 'box/c7 '(set-box! (contract (box/c boolean?) (box 12) 'pos 'neg) 11)) + + (test/neg-blame + 'box/c7 + '(set-box! (contract (box/c boolean? any/c) (box 12) 'pos 'neg) 11)) (test/neg-blame @@ -43,4 +63,13 @@ (box (list values)) 'pos 'neg)]) + ((car (unbox f)) 3))) + + (test/neg-blame + 'box/c-with-cons/c-inside + '(let ([f + (contract (box/c (cons/c (-> boolean? boolean?) '()) any/c) + (box (list values)) + 'pos + 'neg)]) ((car (unbox f)) 3)))) diff --git a/racket/collects/racket/contract/private/box.rkt b/racket/collects/racket/contract/private/box.rkt index b6a8bd8ef7..5f2c1a2e2b 100644 --- a/racket/collects/racket/contract/private/box.rkt +++ b/racket/collects/racket/contract/private/box.rkt @@ -12,10 +12,9 @@ (define/subexpression-pos-prop (box-immutable/c elem) (box/c elem #:immutable #t)) -(define-struct base-box/c (content immutable)) +(define-struct base-box/c (content-w content-r immutable)) (define (check-box/c ctc val blame) - (define elem-ctc (base-box/c-content ctc)) (define immutable (base-box/c-immutable ctc)) (unless (box? val) (raise-blame-error blame val '(expected "a box" given: "~e") val)) @@ -29,7 +28,6 @@ [(dont-care) (void)])) (define (check-box/c-np ctc val blame) - (define elem-ctc (base-box/c-content ctc)) (define immutable (base-box/c-immutable ctc)) (cond [(box? val) @@ -55,7 +53,7 @@ val '(expected "a box" given: "~e") val))])) (define (box/c-first-order ctc) - (define elem-ctc (base-box/c-content ctc)) + (define elem-r-ctc (base-box/c-content-r ctc)) (define immutable (base-box/c-immutable ctc)) (λ (val) (and (box? val) @@ -63,43 +61,50 @@ [(#t) (immutable? val)] [(#f) (not (immutable? val))] [(dont-care) #t]) - (contract-first-order-passes? elem-ctc (unbox val))))) + (contract-first-order-passes? elem-r-ctc (unbox val))))) (define (box/c-name ctc) - (let ([elem-name (contract-name (base-box/c-content ctc))] + (let ([elem-w-name (contract-name (base-box/c-content-w ctc))] + [elem-r-name (contract-name (base-box/c-content-r ctc))] [immutable (base-box/c-immutable ctc)] [flat? (flat-box/c? ctc)]) (apply build-compound-type-name 'box/c - elem-name - (if (and flat? (eq? immutable #t)) - (list '#:immutable #t) - (append - (if (not (eq? immutable 'dont-care)) - (list '#:immutable immutable) - null) - (if flat? - (list '#:flat? #t) - null)))))) + elem-w-name + (append + (if (not (equal? elem-w-name elem-r-name)) + (list elem-r-name) + null) + (if (and flat? (eq? immutable #t)) + (list '#:immutable #t) + (append + (if (not (eq? immutable 'dont-care)) + (list '#:immutable immutable) + null) + (if flat? + (list '#:flat? #t) + null))))))) (define (add-box-context blame) (blame-add-context blame "the content of")) (define (box/c-stronger this that) - (define this-content (base-box/c-content this)) + (define this-content-w (base-box/c-content-w this)) + (define this-content-r (base-box/c-content-r this)) (define this-immutable (base-box/c-immutable this)) (cond [(base-box/c? that) - (define that-content (base-box/c-content that)) + (define that-content-w (base-box/c-content-w that)) + (define that-content-r (base-box/c-content-r that)) (define that-immutable (base-box/c-immutable that)) (cond [(and (equal? this-immutable #t) (equal? that-immutable #t)) - (contract-stronger? this-content that-content)] + (contract-stronger? this-content-r that-content-r)] [(or (equal? that-immutable 'dont-care) (equal? this-immutable that-immutable)) - (and (contract-stronger? this-content that-content) - (contract-stronger? that-content this-content))] + (and (contract-stronger? this-content-r that-content-r) + (contract-stronger? that-content-w this-content-w))] [else #f])] [else #f])) @@ -113,7 +118,7 @@ #:stronger box/c-stronger #:late-neg-projection (λ (ctc) - (define content-ctc (get/build-late-neg-projection (base-box/c-content ctc))) + (define content-ctc (get/build-late-neg-projection (base-box/c-content-w ctc))) (λ (blame) (define box-blame (add-box-context blame)) (define late-neg-proj (content-ctc box-blame)) @@ -129,35 +134,38 @@ (λ (blame) (λ (val) (check-box/c ctc val blame) - (((contract-projection (base-box/c-content ctc)) blame) (unbox val)) + (((contract-projection (base-box/c-content-w ctc)) blame) (unbox val)) val))))) (define (ho-projection box-wrapper) (λ (ctc) - (let ([elem-ctc (base-box/c-content ctc)] + (let ([elem-w-ctc (base-box/c-content-w ctc)] + [elem-r-ctc (base-box/c-content-r ctc)] [immutable (base-box/c-immutable ctc)]) (λ (blame) - (let ([pos-elem-proj ((contract-projection elem-ctc) blame)] - [neg-elem-proj ((contract-projection elem-ctc) (blame-swap blame))]) + (let ([pos-elem-r-proj ((contract-projection elem-r-ctc) blame)] + [neg-elem-w-proj ((contract-projection elem-w-ctc) (blame-swap blame))]) (λ (val) (check-box/c ctc val blame) (if (and (immutable? val) (not (chaperone? val))) - (box-immutable (pos-elem-proj (unbox val))) + (box-immutable (pos-elem-r-proj (unbox val))) (box-wrapper val - (λ (b v) (pos-elem-proj v)) - (λ (b v) (neg-elem-proj v)) + (λ (b v) (pos-elem-r-proj v)) ; unbox-proc + (λ (b v) (neg-elem-w-proj v)) ; set-proc impersonator-prop:contracted ctc impersonator-prop:blame blame)))))))) (define (ho-late-neg-projection chaperone/impersonate-box) (λ (ctc) - (define elem-ctc (base-box/c-content ctc)) + (define elem-w-ctc (base-box/c-content-w ctc)) + (define elem-r-ctc (base-box/c-content-r ctc)) (define immutable (base-box/c-immutable ctc)) - (define vfp (get/build-late-neg-projection elem-ctc)) + (define w-vfp (get/build-late-neg-projection elem-w-ctc)) + (define r-vfp (get/build-late-neg-projection elem-r-ctc)) (λ (blame) (define box-blame (add-box-context blame)) - (define pos-elem-proj (vfp box-blame)) - (define neg-elem-proj (vfp (blame-swap box-blame))) + (define pos-elem-r-proj (r-vfp box-blame)) + (define neg-elem-w-proj (w-vfp (blame-swap box-blame))) (λ (val neg-party) (cond [(check-box/c-np ctc val blame) @@ -165,11 +173,11 @@ (λ (f) (f neg-party))] [else (if (and (immutable? val) (not (chaperone? val))) - (box-immutable (pos-elem-proj (unbox val) neg-party)) + (box-immutable (pos-elem-r-proj (unbox val) neg-party)) (chaperone/impersonate-box val - (λ (b v) (pos-elem-proj v neg-party)) - (λ (b v) (neg-elem-proj v neg-party)) + (λ (b v) (pos-elem-r-proj v neg-party)) + (λ (b v) (neg-elem-w-proj v neg-party)) impersonator-prop:contracted ctc impersonator-prop:blame (blame-add-missing-party blame neg-party)))]))))) @@ -231,17 +239,21 @@ 'racket/contract:contract (vector this-one (list #'b/c) null))))])) -(define (box/c elem #:immutable [immutable 'dont-care] #:flat? [flat? #f]) - (let ([ctc (if flat? - (coerce-flat-contract 'box/c elem) - (coerce-contract 'box/c elem))]) +(define (box/c elem-w [elem-r elem-w] #:immutable [immutable 'dont-care] #:flat? [flat? #f]) + (let ([ctc-w (if flat? + (coerce-flat-contract 'box/c elem-w) + (coerce-contract 'box/c elem-w))] + [ctc-r (if flat? + (coerce-flat-contract 'box/c elem-r) + (coerce-contract 'box/c elem-w))]) (cond [(or flat? (and (eq? immutable #t) - (flat-contract? ctc))) - (make-flat-box/c ctc immutable)] - [(chaperone-contract? ctc) - (make-chaperone-box/c ctc immutable)] + (flat-contract? ctc-r))) + (make-flat-box/c ctc-w ctc-r immutable)] + [(and (chaperone-contract? ctc-w) + (chaperone-contract? ctc-r)) + (make-chaperone-box/c ctc-w ctc-r immutable)] [else - (make-impersonator-box/c ctc immutable)]))) + (make-impersonator-box/c ctc-w ctc-r immutable)]))) From dd97e7b72ee93230593e8de5465dbfb7698c3cb8 Mon Sep 17 00:00:00 2001 From: Alexis King Date: Sat, 24 Oct 2015 13:17:59 -0700 Subject: [PATCH 362/381] Improve how multi-in assigns source location info for its expansion This changes how multi-in is implemented so that the location for each expanded element in the final require spec is tied to the last relevant module path element. This allows DrRacket to intelligently show arrows linking each imported binding with a relevant piece of the multi-in import spec. --- racket/collects/racket/require.rkt | 62 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/racket/collects/racket/require.rkt b/racket/collects/racket/require.rkt index 77e4c96bc4..034df4e551 100644 --- a/racket/collects/racket/require.rkt +++ b/racket/collects/racket/require.rkt @@ -1,6 +1,6 @@ #lang racket/base -(require (for-syntax racket/base racket/require-transform racket/list +(require (for-syntax racket/base racket/require-transform racket/list syntax/stx (only-in racket/syntax syntax-local-eval)) "require-syntax.rkt") @@ -100,24 +100,26 @@ (define-for-syntax (multi xs) (define (loop xs) - (if (null? xs) + (if (stx-null? xs) '(()) - (let ([first (car xs)] - [rest (loop (cdr xs))]) - (if (list? first) - (let ([bads (filter list? first)]) + (let ([first (stx-car xs)] + [rest (loop (stx-cdr xs))]) + (if (stx-list? first) + (let ([bads (filter stx-list? (syntax->list first))]) (if (null? bads) - (append-map (λ (x) (map (λ (y) (cons x y)) rest)) first) - (error 'multi-in "not a simple element" (car bads)))) + (append-map (λ (x) (map (λ (y) (cons x y)) rest)) (syntax->list first)) + (error 'multi-in "not a simple element" (car (syntax->datum bads))))) (map (λ (x) (cons first x)) rest))))) (define options (loop xs)) (define (try pred? ->str str->) - (and (andmap (λ (x) (andmap pred? x)) options) + (and (andmap (λ (x) (andmap pred? (map syntax-e x))) options) (map (λ (x) - (let ([r (apply string-append - (add-between (if ->str (map ->str x) x) - "/"))]) - (if str-> (str-> r) r))) + (let* ([d (map syntax-e x)] + [r (apply string-append + (add-between (if ->str (map ->str d) d) + "/"))] + [ctxt (last x)]) + (datum->syntax ctxt (if str-> (str-> r) r) ctxt ctxt))) options))) (or (try string? #f #f) (try symbol? symbol->string string->symbol) @@ -128,25 +130,25 @@ (syntax-case stx () [(_ elem0 elem ...) (quasisyntax/loc stx - (combine-in #,@(datum->syntax stx (multi (syntax->datum #'(elem0 elem ...))) - stx stx stx)))])) + (combine-in #,@(multi #'(elem0 elem ...))))])) ;; Tests for multi. ;; We don't want to run them every time the file is required, so they are ;; commented out. A proper test suite for racket/require should be written. -;; (require tests/eli-tester) -;; (test (multi '("a" "b" "c")) => '("a/b/c") -;; (multi '("a" ("b" "c") "d")) => '("a/b/d" "a/c/d") -;; (multi '("a" "b" ("c" "d"))) => '("a/b/c" "a/b/d") -;; (multi '(("a" "b") "c" "d")) => '("a/c/d" "b/c/d") -;; (multi '(("a" "b") ("c" "d"))) => '("a/c" "a/d" "b/c" "b/d") -;; (multi '(("a" "b" "c" "d"))) => '("a" "b" "c" "d") -;; (multi '(("a" "b" ("c" "d")))) =error> "" -;; (multi '(a b c)) => '(a/b/c) -;; (multi '(a (b c) d)) => '(a/b/d a/c/d) -;; (multi '(a b (c d))) => '(a/b/c a/b/d) -;; (multi '((a b) c d)) => '(a/c/d b/c/d) -;; (multi '((a b) (c d))) => '(a/c a/d b/c b/d) -;; (multi '((a b c d))) => '(a b c d) -;; (multi '((a b (c d)))) =error> "") +#;(begin-for-syntax + (require tests/eli-tester) + (test (map syntax-e (multi #'("a" "b" "c"))) => '("a/b/c") + (map syntax-e (multi #'("a" ("b" "c") "d"))) => '("a/b/d" "a/c/d") + (map syntax-e (multi #'("a" "b" ("c" "d")))) => '("a/b/c" "a/b/d") + (map syntax-e (multi #'(("a" "b") "c" "d"))) => '("a/c/d" "b/c/d") + (map syntax-e (multi #'(("a" "b") ("c" "d")))) => '("a/c" "a/d" "b/c" "b/d") + (map syntax-e (multi #'(("a" "b" "c" "d")))) => '("a" "b" "c" "d") + (map syntax-e (multi #'(("a" "b" ("c" "d"))))) =error> "" + (map syntax-e (multi #'(a b c))) => '(a/b/c) + (map syntax-e (multi #'(a (b c) d))) => '(a/b/d a/c/d) + (map syntax-e (multi #'(a b (c d)))) => '(a/b/c a/b/d) + (map syntax-e (multi #'((a b) c d))) => '(a/c/d b/c/d) + (map syntax-e (multi #'((a b) (c d)))) => '(a/c a/d b/c b/d) + (map syntax-e (multi #'((a b c d)))) => '(a b c d) + (map syntax-e (multi #'((a b (c d))))) =error> "")) From bf69920570536a06e176260ba225082587bf3913 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 24 Oct 2015 18:31:17 -0500 Subject: [PATCH 363/381] Move racket/require tests. --- pkgs/racket-test/tests/racket/require.rkt | 22 ++++++++++++++++++++++ racket/collects/racket/require.rkt | 22 ++-------------------- 2 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 pkgs/racket-test/tests/racket/require.rkt diff --git a/pkgs/racket-test/tests/racket/require.rkt b/pkgs/racket-test/tests/racket/require.rkt new file mode 100644 index 0000000000..726ae9437f --- /dev/null +++ b/pkgs/racket-test/tests/racket/require.rkt @@ -0,0 +1,22 @@ +#lang racket + +;; Tests for multi. +(module+ test + (require (submod racket/require for-testing)) + (begin-for-syntax + (require tests/eli-tester) + (test (map syntax-e (multi #'("a" "b" "c"))) => '("a/b/c") + (map syntax-e (multi #'("a" ("b" "c") "d"))) => '("a/b/d" "a/c/d") + (map syntax-e (multi #'("a" "b" ("c" "d")))) => '("a/b/c" "a/b/d") + (map syntax-e (multi #'(("a" "b") "c" "d"))) => '("a/c/d" "b/c/d") + (map syntax-e (multi #'(("a" "b") ("c" "d")))) => '("a/c" "a/d" "b/c" "b/d") + (map syntax-e (multi #'(("a" "b" "c" "d")))) => '("a" "b" "c" "d") + (map syntax-e (multi #'(("a" "b" ("c" "d"))))) =error> "" + (map syntax-e (multi #'(a b c))) => '(a/b/c) + (map syntax-e (multi #'(a (b c) d))) => '(a/b/d a/c/d) + (map syntax-e (multi #'(a b (c d)))) => '(a/b/c a/b/d) + (map syntax-e (multi #'((a b) c d))) => '(a/c/d b/c/d) + (map syntax-e (multi #'((a b) (c d)))) => '(a/c a/d b/c b/d) + (map syntax-e (multi #'((a b c d)))) => '(a b c d) + (map syntax-e (multi #'((a b (c d))))) =error> "")) + ) diff --git a/racket/collects/racket/require.rkt b/racket/collects/racket/require.rkt index 034df4e551..c6fc70a5b9 100644 --- a/racket/collects/racket/require.rkt +++ b/racket/collects/racket/require.rkt @@ -132,23 +132,5 @@ (quasisyntax/loc stx (combine-in #,@(multi #'(elem0 elem ...))))])) - -;; Tests for multi. -;; We don't want to run them every time the file is required, so they are -;; commented out. A proper test suite for racket/require should be written. -#;(begin-for-syntax - (require tests/eli-tester) - (test (map syntax-e (multi #'("a" "b" "c"))) => '("a/b/c") - (map syntax-e (multi #'("a" ("b" "c") "d"))) => '("a/b/d" "a/c/d") - (map syntax-e (multi #'("a" "b" ("c" "d")))) => '("a/b/c" "a/b/d") - (map syntax-e (multi #'(("a" "b") "c" "d"))) => '("a/c/d" "b/c/d") - (map syntax-e (multi #'(("a" "b") ("c" "d")))) => '("a/c" "a/d" "b/c" "b/d") - (map syntax-e (multi #'(("a" "b" "c" "d")))) => '("a" "b" "c" "d") - (map syntax-e (multi #'(("a" "b" ("c" "d"))))) =error> "" - (map syntax-e (multi #'(a b c))) => '(a/b/c) - (map syntax-e (multi #'(a (b c) d))) => '(a/b/d a/c/d) - (map syntax-e (multi #'(a b (c d)))) => '(a/b/c a/b/d) - (map syntax-e (multi #'((a b) c d))) => '(a/c/d b/c/d) - (map syntax-e (multi #'((a b) (c d)))) => '(a/c a/d b/c b/d) - (map syntax-e (multi #'((a b c d)))) => '(a b c d) - (map syntax-e (multi #'((a b (c d))))) =error> "")) +(module+ for-testing + (provide (for-syntax multi))) From 95c80cf21f3acf5f7d2a764be04cbda4382fac6c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sat, 24 Oct 2015 20:33:03 -0500 Subject: [PATCH 364/381] Fix test phase. Suggested by Matthew in the PR discussion. --- pkgs/racket-test/tests/racket/require.rkt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test/tests/racket/require.rkt b/pkgs/racket-test/tests/racket/require.rkt index 726ae9437f..1c0db537f9 100644 --- a/pkgs/racket-test/tests/racket/require.rkt +++ b/pkgs/racket-test/tests/racket/require.rkt @@ -1,9 +1,10 @@ #lang racket +(require (submod racket/require for-testing)) + ;; Tests for multi. -(module+ test - (require (submod racket/require for-testing)) - (begin-for-syntax +(begin-for-syntax + (module+ test (require tests/eli-tester) (test (map syntax-e (multi #'("a" "b" "c"))) => '("a/b/c") (map syntax-e (multi #'("a" ("b" "c") "d"))) => '("a/b/d" "a/c/d") @@ -18,5 +19,5 @@ (map syntax-e (multi #'((a b) c d))) => '(a/c/d b/c/d) (map syntax-e (multi #'((a b) (c d)))) => '(a/c a/d b/c b/d) (map syntax-e (multi #'((a b c d)))) => '(a b c d) - (map syntax-e (multi #'((a b (c d))))) =error> "")) - ) + (map syntax-e (multi #'((a b (c d))))) =error> "") + )) From 7338f45bd261e6f8bd1cbbe06052023faf8959a8 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 27 Oct 2015 09:16:50 -0400 Subject: [PATCH 365/381] Fix unwanted reordering of `match` patterns. This change ensures that the `reorder?` flag is passed to recursive calls to `compile` correctly. Related to racket/frtime#1, which is probably now fixed. Merge to 6.3. --- racket/collects/racket/match/compiler.rkt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/racket/collects/racket/match/compiler.rkt b/racket/collects/racket/match/compiler.rkt index 758b20e679..06ce3045c5 100644 --- a/racket/collects/racket/match/compiler.rkt +++ b/racket/collects/racket/match/compiler.rkt @@ -11,6 +11,9 @@ (provide compile*) +;; should we reorder stuff? +(define can-reorder? (make-parameter #t)) + ;; for non-linear patterns (define vars-seen (make-parameter null)) @@ -268,6 +271,7 @@ (define pats (Row-pats row)) ;; all the patterns (define qs (And-ps (car pats))) + (printf ">>> calling compile ~a\n " (append qs (cdr pats))) (compile* (append (map (lambda _ x) qs) xs) (list (make-Row (append qs (cdr pats)) (Row-rhs row) @@ -426,7 +430,7 @@ #'failkv))))))] [else (error 'compile "unsupported pattern: ~a\n" first)])) -(define (compile* vars rows esc [reorder? #t]) +(define (compile* vars rows esc [reorder? (can-reorder?)]) (define (let/wrap clauses body) (if (stx-null? clauses) body @@ -481,7 +485,9 @@ [(f) (generate-temporaries #'(f))] ;; compile the block, with jumps to the previous ;; esc - [c (compile-one vars (car blocks) esc)]) + [c + (parameterize ([can-reorder? reorder?]) + (compile-one vars (car blocks) esc))]) ;; then compile the rest, with our name as the esc (loop (cdr blocks) #'f From d589f6a8ede7b790b94e307a4701e7d07ea7b034 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 26 Oct 2015 09:12:20 -0400 Subject: [PATCH 366/381] Avoid problematic reordering of `Or` patterns. This makes two changes to `(or ...)` pattern compilation. * Avoid reordering the individual elements of an `or` pattern. Since this reordering has broken programs with `and` patterns, avoid it here as well. * Avoid re-ordering sets of patterns that _contain_ an `or`. This is not semantically important for match itself, but Typed Racket relies on the previous behavior. Closes racket/typed-racket#150. Merge to 6.3 --- racket/collects/racket/match/compiler.rkt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/racket/collects/racket/match/compiler.rkt b/racket/collects/racket/match/compiler.rkt index 06ce3045c5..1b0204192a 100644 --- a/racket/collects/racket/match/compiler.rkt +++ b/racket/collects/racket/match/compiler.rkt @@ -234,7 +234,8 @@ #f seen)) qs) - #'esc*)]) + #'esc* + #f)]) ;; then compile the rest of the row (if success? #,(compile* xs @@ -242,7 +243,8 @@ (Row-rhs row) (Row-unmatch row) (append (map cons vars vars) seen))) - esc) + esc + #f) (#,esc))))))] ;; the App rule [(App? first) @@ -271,7 +273,6 @@ (define pats (Row-pats row)) ;; all the patterns (define qs (And-ps (car pats))) - (printf ">>> calling compile ~a\n " (append qs (cdr pats))) (compile* (append (map (lambda _ x) qs) xs) (list (make-Row (append qs (cdr pats)) (Row-rhs row) @@ -473,7 +474,10 @@ ;; and compile each block with a reference to its continuation [else (let*-values - ([(rows vars) (if reorder? + ([(rows vars) (if (and (>= 1 (length vars)) + reorder? + ;; moving Or patterns early breaks Typed Racket + (not (ormap Or? (apply append (map Row-pats rows))))) (reorder-columns rows vars) (values rows vars))] [(fns) From c868c7b68da58e3cb3247454986beb238f52de3f Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Tue, 27 Oct 2015 15:45:13 -0400 Subject: [PATCH 367/381] doc typos --- pkgs/racket-doc/scribblings/reference/strings.scrbl | 2 +- pkgs/racket-doc/scribblings/style/unit.scrbl | 2 +- pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/strings.scrbl b/pkgs/racket-doc/scribblings/reference/strings.scrbl index a2abd656be..9439bb362a 100644 --- a/pkgs/racket-doc/scribblings/reference/strings.scrbl +++ b/pkgs/racket-doc/scribblings/reference/strings.scrbl @@ -91,7 +91,7 @@ Returns an immutable string with the same content as characters long, and that contains the same characters as @racket[str] from @racket[start] inclusive to @racket[end] exclusive. The first position in a string corresponds to @racket[0], so - the @racket[start] and @racket[end] arguments so they must be less than or + the @racket[start] and @racket[end] arguments must be less than or equal to the length of @racket[str], and @racket[end] must be greater than or equal to @racket[start], otherwise the @exnraise[exn:fail:contract]. diff --git a/pkgs/racket-doc/scribblings/style/unit.scrbl b/pkgs/racket-doc/scribblings/style/unit.scrbl index ed8329ae00..56cea86224 100644 --- a/pkgs/racket-doc/scribblings/style/unit.scrbl +++ b/pkgs/racket-doc/scribblings/style/unit.scrbl @@ -482,7 +482,7 @@ mutually recursive functions with modules. This capability is unique to @image["mut-rec-contracts.png" #:scale .8]{Mutually recursive functions with contracts} In contrast, submodules act exactly like plain modules when it comes to -contract boundaries. Like @racket[define/contract], a submodue establishes +contract boundaries. Like @racket[define/contract], a submodule establishes a contract boundary between itself and the rest of the module. Any value flow between a client module and the submodule is governed by contracts. Any value flow within the submodule is free of any constraints. diff --git a/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl index 4681ba3286..7d7a9c766a 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/stxclasses.scrbl @@ -134,7 +134,7 @@ pattern}. @defform*[#:literals (pattern) [(define-splicing-syntax-class name-id stxclass-option ... stxclass-variant ...+) - (define-splicing-syntax-class (name-id kw-formals) stxclass-option ... + (define-splicing-syntax-class (name-id . kw-formals) stxclass-option ... stxclass-variant ...+)]]{ Defines @racket[name-id] as a @deftech{splicing syntax class}, From 8f681cec7abd4d29c09708988e5fc5722bbaf7f2 Mon Sep 17 00:00:00 2001 From: Spencer Florence Date: Wed, 28 Oct 2015 09:17:23 -0400 Subject: [PATCH 368/381] fixed minor docs typo --- pkgs/racket-doc/scribblings/reference/stx-trans.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl index 838031d524..db3f8f36b3 100644 --- a/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl +++ b/pkgs/racket-doc/scribblings/reference/stx-trans.scrbl @@ -701,7 +701,7 @@ then the @exnraise[exn:fail:contract].} Lifts a @racket[#%require] form corresponding to @racket[raw-require-spec] (either as a @tech{syntax object} or datum) to the top-level or to the top of the module currently being expanded - or to an enclosing @racket[begin-for-syntax].. + or to an enclosing @racket[begin-for-syntax]. The resulting syntax object is the same as @racket[stx], except that a fresh @tech{scope} is added. The same @tech{scope} is From 2396542cdaae8143189fd72cf6eac8aa6687cb3a Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Wed, 28 Oct 2015 11:32:14 -0400 Subject: [PATCH 369/381] better locking test --- pkgs/racket-test/tests/pkg/tests-locking.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test/tests/pkg/tests-locking.rkt b/pkgs/racket-test/tests/pkg/tests-locking.rkt index 767c70f8e3..0cd93a2d0e 100644 --- a/pkgs/racket-test/tests/pkg/tests-locking.rkt +++ b/pkgs/racket-test/tests/pkg/tests-locking.rkt @@ -14,11 +14,13 @@ ;; Step 1: Start a special server that waits for our signal to respond (initialize-catalogs) + (define okay-to-start?-sema (make-semaphore)) (define okay-to-respond?-sema (make-semaphore)) (thread (λ () (serve/servlet (pkg-index/basic (λ (pkg-name) + (semaphore-post okay-to-start?-sema) (semaphore-wait okay-to-respond?-sema) (define r (hash-ref *index-ht-1* pkg-name #f)) r) @@ -36,7 +38,7 @@ (λ () (shelly-begin $ "raco pkg install pkg-test1"))) - (sleep 2) + (semaphore-wait okay-to-start?-sema) ;; Step 4: Start the installation request that will fail $ "raco pkg install pkg-test1" =exit> 1 From 0edd78192891ecf7a8b565d52b966a73c5e85a27 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 28 Oct 2015 17:41:14 -0400 Subject: [PATCH 370/381] use "_LOCK" prefix for Windows cross-build Use "_LOCK" instead of ".LOCK" when the cross platform is Windows, not just when the current platform is Windows. Merge to v6.3 --- pkgs/racket-doc/scribblings/reference/filesystem.scrbl | 6 ++++-- racket/collects/racket/file.rkt | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index 8c08380f8a..06b107fa24 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -3,7 +3,8 @@ (for-label framework/preferences racket/runtime-path launcher/launcher - setup/dirs)) + setup/dirs + setup/cross-system)) @(define file-eval (make-base-eval)) @(interaction-eval #:eval file-eval (begin (require racket/file) (define filename (make-temporary-file)))) @@ -1402,7 +1403,8 @@ in the sense of @racket[port-try-file-lock?]. [name path-element?]) path?])]{ -Creates a lock filename by prepending @racket["_LOCK"] on Windows or +Creates a lock filename by prepending @racket["_LOCK"] on Windows +(i.e., when @racket[cross-system-type] reports @racket['windows]) or @racket[".LOCK"] on other platforms to the file portion of the path. @examples[ diff --git a/racket/collects/racket/file.rkt b/racket/collects/racket/file.rkt index 47938ed822..206c85fdc4 100644 --- a/racket/collects/racket/file.rkt +++ b/racket/collects/racket/file.rkt @@ -1,6 +1,7 @@ #lang racket/base (require "path.rkt" setup/dirs + setup/cross-system (for-syntax racket/base setup/path-to-relative)) @@ -278,7 +279,7 @@ (define (make-pathless-lock-file-name name) (bytes->path-element (bytes-append - (if (eq? 'windows (system-type)) + (if (eq? 'windows (cross-system-type)) #"_" #".") #"LOCK" From d17cc6039bd7151b504b9cab220a56c6540e0ed1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 28 Oct 2015 21:10:40 -0400 Subject: [PATCH 371/381] repair `syntax-local-lift-require` to top level In `syntax-local-lift-require`, avoid scope adjustments intended to deal with `require` forms that are compiled in one namespace and evaluated in another. --- .../racket-test-core/tests/racket/module.rktl | 23 +++++++++++++++++++ racket/src/racket/src/module.c | 13 +++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 44dda840c1..ecf51d4ab2 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1600,6 +1600,29 @@ case of module-leve bindings; it doesn't cover local bindings. (require (rename-in 'shadows-a-racket-base-binding-and-exports-all [path? other-path?])))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check `syntax-local-lift-require` on an +;; spec that doesn't have the target environment's +;; context: + +(module has-a-submodule-that-exports-x racket + (module b racket/base + (define x 1) + (provide x)) + + (define-syntax (lifted-require-of-x stx) + (syntax-case stx () + [(_ mod) + (let ([x (car (generate-temporaries '(x)))]) + (syntax-local-lift-require + #`(rename mod #,x x) + x))])) + + (provide lifted-require-of-x)) + +(require 'has-a-submodule-that-exports-x) + +(test 1 values (lifted-require-of-x (submod 'has-a-submodule-that-exports-x b))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index ccb262cab2..1e9baef4f3 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -12581,12 +12581,14 @@ static Scheme_Object *check_require_form(Scheme_Env *env, Scheme_Object *form) } static Scheme_Object * -do_require_execute(Scheme_Env *env, Scheme_Object *form) +do_require_execute(Scheme_Env *env, Scheme_Object *form, int to_context) { Scheme_Object *modidx; - /* Use the current top-level context: */ - form = scheme_stx_from_generic_to_module_context(form, env->stx_context); + if (to_context) { + /* Use the current top-level context: */ + form = scheme_stx_from_generic_to_module_context(form, env->stx_context); + } /* Check for collisions again, in case there's a difference between compile and run times: */ @@ -12608,7 +12610,8 @@ Scheme_Object * scheme_top_level_require_execute(Scheme_Object *data) { do_require_execute(scheme_environment_from_dummy(SCHEME_PTR1_VAL(data)), - SCHEME_PTR2_VAL(data)); + SCHEME_PTR2_VAL(data), + 1); return scheme_void; } @@ -12674,7 +12677,7 @@ Scheme_Object *scheme_toplevel_require_for_expand(Scheme_Object *module_path, form = scheme_revert_use_site_scopes(form, cenv); - do_require_execute(cenv->genv, form); + do_require_execute(cenv->genv, form, 0); return form; } From 3f208036796c5f5fcd8ec900f74af4b242720298 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 28 Oct 2015 20:22:16 -0500 Subject: [PATCH 372/381] implement predicate/c for the more complex arrow contract protocol So now (-> any/c integer?) will avoid the chaperone wrapper when the function is a struct predicate while simultaneously supporting the "extra argument neg party" protocol --- .../tests/racket/contract/arrow-neg-party.rkt | 17 +- .../tests/racket/contract/arrow.rkt | 24 +++ .../tests/racket/contract/name.rkt | 2 + racket/collects/racket/contract/base.rkt | 1 + .../contract/private/arrow-higher-order.rkt | 31 +-- .../contract/private/arrow-val-first.rkt | 188 ++++++++++++------ .../racket/contract/private/arrow.rkt | 111 +++++------ .../collects/racket/contract/private/misc.rkt | 2 +- .../racket/contract/private/opters.rkt | 10 +- 9 files changed, 242 insertions(+), 144 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt b/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt index 43bc166f8a..e9583fa296 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow-neg-party.rkt @@ -270,4 +270,19 @@ (->* (any/c) (#:kw any/c) any) (λ (x #:kw [kw 0]) x)) 'neg 42) - 42)) + 42) + + (test/pos-blame + '->neg-party23 + '((neg-party-fn + (-> any/c boolean?) + (λ (x) 1)) + 'neg 1)) + + (test/spec-passed/result + '->neg-party24 + '((neg-party-fn + (-> any/c boolean?) + (λ (x) #t)) + 'neg 1) + #t)) diff --git a/pkgs/racket-test/tests/racket/contract/arrow.rkt b/pkgs/racket-test/tests/racket/contract/arrow.rkt index 4876bc1233..8191ff0f9b 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow.rkt @@ -353,6 +353,30 @@ (test/spec-passed 'predicate/c4 '((contract predicate/c (λ (x) #t) 'pos 'neg) 12)) + (test/spec-passed/result + 'predicate/c5 + '(let () + (struct s ()) + (eq? (contract (-> any/c boolean?) s? 'pos 'neg) s?)) + #t) + (test/spec-passed/result + 'predicate/c6 + '(let () + (struct s ()) + (eq? (contract predicate/c s? 'pos 'neg) s?)) + #t) + (test/pos-blame + 'predicate/c7 + '(contract (-> any/c boolean?) 1 'pos 'neg)) + (test/pos-blame + 'predicate/c8 + '(contract (-> any/c boolean?) (λ (x y) 1) 'pos 'neg)) + (test/pos-blame + 'predicate/c9 + '((contract (-> any/c boolean?) (λ (x) 1) 'pos 'neg) 12)) + (test/spec-passed + 'predicate/c10 + '((contract (-> any/c boolean?) (λ (x) #t) 'pos 'neg) 12)) ;; this test ensures that no contract wrappers ;; are created for struct predicates diff --git a/pkgs/racket-test/tests/racket/contract/name.rkt b/pkgs/racket-test/tests/racket/contract/name.rkt index a077488eb7..4c93ca5860 100644 --- a/pkgs/racket-test/tests/racket/contract/name.rkt +++ b/pkgs/racket-test/tests/racket/contract/name.rkt @@ -47,6 +47,8 @@ (->* (integer? boolean?) () (values char? any/c))) (test-name '(-> integer? boolean? any) (->* (integer? boolean?) () any)) (test-name '(-> integer? boolean? #:x string? any) (-> integer? #:x string? boolean? any)) + (test-name '(-> any/c boolean?) (-> any/c boolean?)) + (test-name 'predicate/c predicate/c) (test-name '(->* (integer?) (string?) #:rest any/c (values char? any/c)) (->* (integer?) (string?) #:rest any/c (values char? any/c))) diff --git a/racket/collects/racket/contract/base.rkt b/racket/collects/racket/contract/base.rkt index d0d34b5ed1..3992d7610a 100644 --- a/racket/collects/racket/contract/base.rkt +++ b/racket/collects/racket/contract/base.rkt @@ -35,6 +35,7 @@ -> ->*) (rename-out [->2 ->] [->*2 ->*]) dynamic->* + predicate/c (all-from-out "private/arr-i.rkt" "private/box.rkt" diff --git a/racket/collects/racket/contract/private/arrow-higher-order.rkt b/racket/collects/racket/contract/private/arrow-higher-order.rkt index f8b8f4ae64..bcff1fc39d 100644 --- a/racket/collects/racket/contract/private/arrow-higher-order.rkt +++ b/racket/collects/racket/contract/private/arrow-higher-order.rkt @@ -406,20 +406,23 @@ (define (successfully-got-the-right-kind-of-function val neg-party) (define chap/imp-func (apply chaperone-constructor orig-blame val neg-party the-args)) - (if post? - (chaperone-or-impersonate-procedure - val - chap/imp-func - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party orig-blame neg-party)) - (chaperone-or-impersonate-procedure - val - chap/imp-func - impersonator-prop:contracted ctc - impersonator-prop:blame (blame-add-missing-party orig-blame neg-party) - impersonator-prop:application-mark (cons arrow:contract-key - ;; is this right? - partial-ranges)))) + (cond + [chap/imp-func + (if post? + (chaperone-or-impersonate-procedure + val + chap/imp-func + impersonator-prop:contracted ctc + impersonator-prop:blame (blame-add-missing-party orig-blame neg-party)) + (chaperone-or-impersonate-procedure + val + chap/imp-func + impersonator-prop:contracted ctc + impersonator-prop:blame (blame-add-missing-party orig-blame neg-party) + impersonator-prop:application-mark (cons arrow:contract-key + ;; is this right? + partial-ranges)))] + [else val])) (cond [late-neg? diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index c77351bd24..bac9983107 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -18,10 +18,11 @@ (for-syntax ->2-handled? ->*2-handled? ->-valid-app-shapes - ->*-valid-app-shapes)) + ->*-valid-app-shapes) + (rename-out [-predicate/c predicate/c])) (define-for-syntax (->2-handled? stx) - (syntax-case stx (any values any/c) + (syntax-case stx (any values any/c boolean?) [(_ args ...) (syntax-parameter-value #'arrow:making-a-method) #f] @@ -781,6 +782,18 @@ (flat-contract? (car rngs)) (eq? void? (flat-contract-predicate (car rngs)))) ->void-contract] + [(and (pair? regular-doms) + (null? (cdr regular-doms)) + (any/c? (car regular-doms)) + (null? kwd-infos) + (not rest-ctc) + (not pre-cond) + (not post-cond) + (pair? rngs) + (null? (cdr rngs)) + (flat-contract? (car rngs)) + (eq? boolean? (flat-contract-predicate (car rngs)))) + any/c->boolean-contract] [(and (andmap chaperone-contract? regular-doms) (andmap (λ (x) (chaperone-contract? (kwd-info-ctc x))) kwd-infos) (andmap chaperone-contract? (or rngs '()))) @@ -1061,62 +1074,65 @@ (λ (fuel) (values void '()))])) (define (base->-name ctc) - (define rngs (base->-rngs ctc)) - (define rng-sexp - (cond - [(not rngs) 'any] - [(= 1 (length rngs)) - (contract-name (car rngs))] - [else - `(values ,@(map contract-name rngs))])) (cond - [(and (andmap kwd-info-mandatory? (base->-kwd-infos ctc)) - (= (base->-min-arity ctc) - (length (base->-doms ctc))) - (not (base->-rest ctc)) - (not (base->-pre? ctc)) - (not (base->-post? ctc))) - `(-> ,@(map contract-name (base->-doms ctc)) - ,@(apply - append - (for/list ([kwd-info (base->-kwd-infos ctc)]) - (list (kwd-info-kwd kwd-info) - (contract-name (kwd-info-ctc kwd-info))))) - ,rng-sexp)] + [(predicate/c? ctc) 'predicate/c] [else - (define (take l n) (reverse (list-tail (reverse l) (- (length l) n)))) - (define mandatory-args - `(,@(map contract-name (take (base->-doms ctc) (base->-min-arity ctc))) - ,@(apply - append - (for/list ([kwd-info (base->-kwd-infos ctc)] - #:when (kwd-info-mandatory? kwd-info)) - (list (kwd-info-kwd kwd-info) - (contract-name (kwd-info-ctc kwd-info))))))) - - (define optional-args - `(,@(map contract-name (list-tail (base->-doms ctc) (base->-min-arity ctc))) - ,@(apply - append - (for/list ([kwd-info (base->-kwd-infos ctc)] - #:when (not (kwd-info-mandatory? kwd-info))) - (list (kwd-info-kwd kwd-info) - (contract-name (kwd-info-ctc kwd-info))))))) - - `(->* ,mandatory-args - ,@(if (null? optional-args) - '() - (list optional-args)) - ,@(if (base->-rest ctc) - (list '#:rest (contract-name (base->-rest ctc))) - (list)) - ,@(if (base->-pre? ctc) - (list '#:pre '...) - (list)) - ,rng-sexp - ,@(if (base->-post? ctc) - (list '#:post '...) - (list)))])) + (define rngs (base->-rngs ctc)) + (define rng-sexp + (cond + [(not rngs) 'any] + [(= 1 (length rngs)) + (contract-name (car rngs))] + [else + `(values ,@(map contract-name rngs))])) + (cond + [(and (andmap kwd-info-mandatory? (base->-kwd-infos ctc)) + (= (base->-min-arity ctc) + (length (base->-doms ctc))) + (not (base->-rest ctc)) + (not (base->-pre? ctc)) + (not (base->-post? ctc))) + `(-> ,@(map contract-name (base->-doms ctc)) + ,@(apply + append + (for/list ([kwd-info (base->-kwd-infos ctc)]) + (list (kwd-info-kwd kwd-info) + (contract-name (kwd-info-ctc kwd-info))))) + ,rng-sexp)] + [else + (define (take l n) (reverse (list-tail (reverse l) (- (length l) n)))) + (define mandatory-args + `(,@(map contract-name (take (base->-doms ctc) (base->-min-arity ctc))) + ,@(apply + append + (for/list ([kwd-info (base->-kwd-infos ctc)] + #:when (kwd-info-mandatory? kwd-info)) + (list (kwd-info-kwd kwd-info) + (contract-name (kwd-info-ctc kwd-info))))))) + + (define optional-args + `(,@(map contract-name (list-tail (base->-doms ctc) (base->-min-arity ctc))) + ,@(apply + append + (for/list ([kwd-info (base->-kwd-infos ctc)] + #:when (not (kwd-info-mandatory? kwd-info))) + (list (kwd-info-kwd kwd-info) + (contract-name (kwd-info-ctc kwd-info))))))) + + `(->* ,mandatory-args + ,@(if (null? optional-args) + '() + (list optional-args)) + ,@(if (base->-rest ctc) + (list '#:rest (contract-name (base->-rest ctc))) + (list)) + ,@(if (base->-pre? ctc) + (list '#:pre '...) + (list)) + ,rng-sexp + ,@(if (base->-post? ctc) + (list '#:post '...) + (list)))])])) (define ((->-first-order ctc) x) (define l (base->-min-arity ctc)) @@ -1204,6 +1220,11 @@ prop:chaperone-contract (make-property build-chaperone-contract-property chaperone-procedure)) +(define-struct (predicate/c base->) () + #:property + prop:chaperone-contract + (make-property build-chaperone-contract-property chaperone-procedure)) + (define-struct (impersonator-> base->) () #:property prop:contract @@ -1212,8 +1233,11 @@ (define ->void-contract (let-syntax ([get-chaperone-constructor (λ (_) - ;; relies on the popular key (0 0 () () #f 1) appearing first - (define ids (list-ref popular-key-ids 0)) + (define desired-key '(0 0 () () #f 1)) + (define expected-index 0) + (unless (equal? desired-key (list-ref popular-keys expected-index)) + (error '->void-contract "expected the 0th key to be ~s" desired-key)) + (define ids (list-ref popular-key-ids expected-index)) (list-ref ids 1))]) (make--> 0 '() '() #f #f (list (coerce-contract 'whatever void?)) @@ -1232,3 +1256,51 @@ [args (wrong-number-of-results-blame blame neg-party f args 1)])))) (get-chaperone-constructor)))) + +(define (mk-any/c->boolean-contract constructor) + (define (rng-checker f blame neg-party) + (case-lambda + [(rng) + (if (boolean? rng) + rng + (raise-blame-error blame #:missing-party neg-party rng + '(expected: "boolean?" given: "~e") + rng))] + [args + (wrong-number-of-results-blame blame neg-party f args 1)])) + (constructor 1 (list any/c) '() #f #f + (list (coerce-contract 'whatever boolean?)) + #f + (λ (blame f _ignored-dom-contract _ignored-rng-contract) + (λ (neg-party argument) + (call-with-values + (λ () (f argument)) + (rng-checker f blame neg-party)))) + (λ (blame f neg-party _ignored-dom-contract _ignored-rng-contract) + (unless (procedure? f) + (raise-blame-error + blame #:missing-party neg-party f + '(expected: "a procedure" given: "~e") + f)) + (unless (procedure-arity-includes? f 1) + (raise-blame-error + blame #:missing-party neg-party f + '(expected: "a procedure that accepts 1 non-keyword argument" + given: "~e") + f)) + (cond + [(struct-predicate-procedure? f) #f] + [(equal? (procedure-arity f) 1) + (λ (arg) + (values (rng-checker f blame neg-party) arg))] + [(procedure-arity-includes? f 1) + (make-keyword-procedure + (λ (kwds kwd-args . other) + (unless (null? kwds) + (arrow:raise-no-keywords-arg blame f kwds)) + (unless (= 1 (length other)) + (arrow:raise-wrong-number-of-args-error blame f (length other) 1 1 1)) + (values (rng-checker f blame neg-party) '() (car other))))])))) + +(define -predicate/c (mk-any/c->boolean-contract predicate/c)) +(define any/c->boolean-contract (mk-any/c->boolean-contract make-->)) diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index 8f0202189c..6d25281615 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -21,7 +21,6 @@ base->-doms/c unconstrained-domain-> the-unsupplied-arg - (rename-out [-predicate/c predicate/c]) unsupplied-arg? making-a-method method-contract? @@ -40,7 +39,9 @@ arity-checking-wrapper unspecified-dom blame-add-range-context - blame-add-nth-arg-context) + blame-add-nth-arg-context + raise-no-keywords-arg + raise-wrong-number-of-args-error) (define-syntax-parameter making-a-method #f) (define-syntax-parameter method-contract? #f) @@ -394,16 +395,6 @@ basic-lambda kwd-lambda)] [else - (define arity-string - (if max-arity - (cond - [(= min-method-arity max-method-arity) - (format "~a non-keyword argument~a" min-method-arity (if (= min-method-arity 1) "" "s"))] - [(= (+ min-method-arity 1) max-method-arity) - (format "~a or ~a non-keyword arguments" min-method-arity max-method-arity)] - [else - (format "~a to ~a non-keyword arguments" min-method-arity max-method-arity)]) - (format "at least ~a non-keyword argument~a" min-method-arity (if (= min-method-arity 1) "" "s")))) (define-values (vr va) (procedure-keywords val)) (define all-kwds (append req-kwd opt-kwd)) (define (valid-number-of-args? args) @@ -413,31 +404,16 @@ (define kwd-checker (if (and (null? req-kwd) (null? opt-kwd)) (λ (kwds kwd-args . args) - (raise-blame-error (blame-swap blame) val - (list 'expected: - "no keywords" - 'given: - (apply - string-append - (let loop ([kwds kwds]) - (cond - [(null? kwds) '()] - [(null? (cdr kwds)) - (list "#:" (keyword->string (car kwds)))] - [else - (list* "#:" - (keyword->string (car kwds)) - " " - (loop (cdr kwds)))])))))) + (raise-no-keywords-arg blame val kwds)) (λ (kwds kwd-args . args) (with-continuation-mark contract-continuation-mark-key blame (let () (define args-len (length args)) (unless (valid-number-of-args? args) - (raise-blame-error (blame-swap blame) val - '(received: "~a argument~a" expected: "~a") - args-len (if (= args-len 1) "" "s") arity-string)) + (raise-wrong-number-of-args-error + blame val + args-len max-arity min-method-arity max-method-arity)) ;; these two for loops are doing O(n^2) work that could be linear ;; (since the keyword lists are sorted) @@ -460,9 +436,9 @@ (let () (unless (valid-number-of-args? args) (define args-len (length args)) - (raise-blame-error (blame-swap blame) val - '(received: "~a argument~a" expected: "~a") - args-len (if (= args-len 1) "" "s") arity-string)) + (raise-wrong-number-of-args-error + blame val + args-len max-arity min-method-arity max-method-arity)) (apply basic-lambda args)))) (λ args (raise-blame-error (blame-swap blame) val @@ -472,6 +448,41 @@ (make-keyword-procedure kwd-checker basic-checker-name) basic-checker-name)])) +(define (raise-wrong-number-of-args-error + blame val + args-len max-arity min-method-arity max-method-arity) + (define arity-string + (if max-arity + (cond + [(= min-method-arity max-method-arity) + (format "~a non-keyword argument~a" min-method-arity (if (= min-method-arity 1) "" "s"))] + [(= (+ min-method-arity 1) max-method-arity) + (format "~a or ~a non-keyword arguments" min-method-arity max-method-arity)] + [else + (format "~a to ~a non-keyword arguments" min-method-arity max-method-arity)]) + (format "at least ~a non-keyword argument~a" min-method-arity (if (= min-method-arity 1) "" "s")))) + (raise-blame-error (blame-swap blame) val + '(received: "~a argument~a" expected: "~a") + args-len (if (= args-len 1) "" "s") arity-string)) + +(define (raise-no-keywords-arg blame val given-kwds) + (raise-blame-error (blame-swap blame) val + (list 'expected: + "no keywords" + 'given: + (apply + string-append + (let loop ([kwds given-kwds]) + (cond + [(null? kwds) '()] + [(null? (cdr kwds)) + (list "#:" (keyword->string (car kwds)))] + [else + (list* "#:" + (keyword->string (car kwds)) + " " + (loop (cdr kwds)))])))))) + ;; pre : (or/c #f (-> any)) -- checks the pre-condition, if there is one. ;; post : (or/c #f (-> any)) -- checks the post-condition, if there is one. ;; doms : (listof contract) @@ -1822,34 +1833,6 @@ (λ (x) (send o m x))))) -(define predicate/c-private->ctc - (let-syntax ([m (λ (stx) - ;; we don't use -> directly here to avoid a circularity, since - ;; (-> any/c boolean?) expands into the identifier -predicate/c - (syntax-case stx () - [(_ arg) - #`(syntax-parameterize ((making-a-method #f)) #,(->/proc/main #'arg))]))]) - (let ([predicate/c (m (-> any/c boolean?))]) - predicate/c))) - -(struct predicate/c () - #:property prop:custom-write custom-write-property-proc - #:property prop:chaperone-contract - (build-chaperone-contract-property - #:projection (let ([pc (contract-struct-projection predicate/c-private->ctc)]) - (λ (ctc) - (λ (blame) - (let ([proj (pc blame)]) - (λ (val) - (if (struct-predicate-procedure? val) - val - (proj val))))))) - #:name (lambda (ctc) 'predicate/c) - #:first-order (let ([f (contract-struct-first-order predicate/c-private->ctc)]) (λ (ctc) f)) - #:stronger (λ (this that) (contract-struct-stronger? predicate/c-private->ctc that)))) - -(define -predicate/c (predicate/c)) - (define-syntax (-> stx) (syntax-case stx (any any/c boolean?) [(_ any/c ... any) @@ -1860,10 +1843,6 @@ '(-> #,@(build-list dom-len (λ (x) 'any/c)) any) (λ (x) (procedure-arity-includes?/no-kwds x #,dom-len))))] - [(_ any/c boolean?) - ;; special case (-> any/c boolean?) to use predicate/c - (not (syntax-parameter-value #'making-a-method)) - #'-predicate/c] [_ #`(syntax-parameterize ((making-a-method #f)) #,(->/proc/main stx))])) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index 2adcd4cedb..7477a0e1aa 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -32,7 +32,7 @@ parameter/c procedure-arity-includes/c - any/c + any/c any/c? any none/c make-none/c diff --git a/racket/collects/racket/contract/private/opters.rkt b/racket/collects/racket/contract/private/opters.rkt index 763f8677f2..14d849abee 100644 --- a/racket/collects/racket/contract/private/opters.rkt +++ b/racket/collects/racket/contract/private/opters.rkt @@ -434,7 +434,7 @@ [(_ content) (opt/listof-ctc #'content #t opt/i opt/info)])) -(define-for-syntax (predicate/c-optres opt/info) +(define-for-syntax (predicate/c-optres opt/info has-name-predicate/c?) (build-optres #:exp (with-syntax ((val (opt/info-val opt/info)) @@ -472,7 +472,9 @@ #:opt #f #:stronger-ribs null #:chaperone #t - #:name #''predicate/c)) + #:name (if has-name-predicate/c? + #''predicate/c + #''(-> any/c boolean?)))) ;; ;; arrow opter @@ -698,7 +700,7 @@ #:chaperone #t #:name #`'(-> #,@(build-list (syntax-e #'n) (λ (x) 'any/c)) any)))] [(_ any/c boolean?) - (predicate/c-optres opt/info)] + (predicate/c-optres opt/info #f)] [(_ dom ... (values rng ...)) (if (ormap (λ (x) (keyword? (syntax-e x))) (syntax->list #'(dom ...))) (opt/unknown opt/i opt/info stx) ;; give up if there is a mandatory keyword @@ -737,7 +739,7 @@ (define opt->/c-cm-key (gensym 'opt->/c-cm-key)) -(define/opter (predicate/c opt/i opt/info stx) (predicate/c-optres opt/info)) +(define/opter (predicate/c opt/i opt/info stx) (predicate/c-optres opt/info #t)) (define (handle-non-exact-procedure val dom-len blame exact-proc) (check-procedure val #f dom-len 0 '() '() blame) From aa46d1bc107c0b9a81c4d87906e2f0c0f56cfc6c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 29 Oct 2015 13:33:28 -0500 Subject: [PATCH 373/381] fix predicate/c bugs --- pkgs/racket-test/tests/racket/contract/arrow.rkt | 9 +++++++++ .../racket/contract/private/arrow-val-first.rkt | 12 ++++++++---- racket/collects/racket/contract/private/arrow.rkt | 6 ++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test/tests/racket/contract/arrow.rkt b/pkgs/racket-test/tests/racket/contract/arrow.rkt index 8191ff0f9b..7d822464b7 100644 --- a/pkgs/racket-test/tests/racket/contract/arrow.rkt +++ b/pkgs/racket-test/tests/racket/contract/arrow.rkt @@ -377,6 +377,15 @@ (test/spec-passed 'predicate/c10 '((contract (-> any/c boolean?) (λ (x) #t) 'pos 'neg) 12)) + (test/spec-passed + 'predicate/c11 + '((contract (-> any/c boolean?) (λ x #t) 'pos 'neg) 12)) + (test/neg-blame + 'predicate/c12 + '((contract (-> any/c boolean?) (λ (x #:y [y 1]) #t) 'pos 'neg) 12 #:y 1)) + (test/pos-blame + 'predicate/c13 + '(contract (-> any/c boolean?) (λ (x #:y y) #t) 'pos 'neg)) ;; this test ensures that no contract wrappers ;; are created for struct predicates diff --git a/racket/collects/racket/contract/private/arrow-val-first.rkt b/racket/collects/racket/contract/private/arrow-val-first.rkt index bac9983107..84bf657b79 100644 --- a/racket/collects/racket/contract/private/arrow-val-first.rkt +++ b/racket/collects/racket/contract/private/arrow-val-first.rkt @@ -1290,17 +1290,21 @@ f)) (cond [(struct-predicate-procedure? f) #f] - [(equal? (procedure-arity f) 1) + [(and (equal? (procedure-arity f) 1) + (let-values ([(required mandatory) (procedure-keywords f)]) + (and (null? required) + (null? mandatory)))) (λ (arg) (values (rng-checker f blame neg-party) arg))] [(procedure-arity-includes? f 1) (make-keyword-procedure (λ (kwds kwd-args . other) (unless (null? kwds) - (arrow:raise-no-keywords-arg blame f kwds)) + (arrow:raise-no-keywords-arg blame #:missing-party neg-party f kwds)) (unless (= 1 (length other)) - (arrow:raise-wrong-number-of-args-error blame f (length other) 1 1 1)) - (values (rng-checker f blame neg-party) '() (car other))))])))) + (arrow:raise-wrong-number-of-args-error #:missing-party neg-party + blame f (length other) 1 1 1)) + (values (rng-checker f blame neg-party) (car other))))])))) (define -predicate/c (mk-any/c->boolean-contract predicate/c)) (define any/c->boolean-contract (mk-any/c->boolean-contract make-->)) diff --git a/racket/collects/racket/contract/private/arrow.rkt b/racket/collects/racket/contract/private/arrow.rkt index 6d25281615..42dd7ee2ee 100644 --- a/racket/collects/racket/contract/private/arrow.rkt +++ b/racket/collects/racket/contract/private/arrow.rkt @@ -449,7 +449,7 @@ basic-checker-name)])) (define (raise-wrong-number-of-args-error - blame val + blame #:missing-party [missing-party #f] val args-len max-arity min-method-arity max-method-arity) (define arity-string (if max-arity @@ -462,11 +462,13 @@ (format "~a to ~a non-keyword arguments" min-method-arity max-method-arity)]) (format "at least ~a non-keyword argument~a" min-method-arity (if (= min-method-arity 1) "" "s")))) (raise-blame-error (blame-swap blame) val + #:missing-party missing-party '(received: "~a argument~a" expected: "~a") args-len (if (= args-len 1) "" "s") arity-string)) -(define (raise-no-keywords-arg blame val given-kwds) +(define (raise-no-keywords-arg blame #:missing-party [missing-party #f] val given-kwds) (raise-blame-error (blame-swap blame) val + #:missing-party missing-party (list 'expected: "no keywords" 'given: From c3aa266bee6c39bb4fc2dcfacee6911b340a235b Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 21 Oct 2015 16:37:40 -0500 Subject: [PATCH 374/381] Flush the same port we write to. --- racket/src/racket/src/print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index efc1a1df30..e0cb524dea 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -263,7 +263,7 @@ void scheme_debug_print (Scheme_Object *obj) { scheme_write(obj, scheme_orig_stdout_port); - fflush (stdout); + scheme_flush_output(scheme_orig_stdout_port); } static void *print_to_port_k(void) From d00401ccc114cf05a75abf7ed915565bbd2d9d06 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 12 Oct 2015 16:40:21 -0500 Subject: [PATCH 375/381] Use faster `reverse` inside racket/private/list proper. --- racket/collects/racket/private/list.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racket/collects/racket/private/list.rkt b/racket/collects/racket/private/list.rkt index 7dfdf9bd19..f53bf09974 100644 --- a/racket/collects/racket/private/list.rkt +++ b/racket/collects/racket/private/list.rkt @@ -1,5 +1,5 @@ (module list "pre-base.rkt" - (require "reverse.rkt") + (require (rename-in "reverse.rkt" [alt-reverse reverse])) (provide foldl foldr @@ -27,7 +27,7 @@ build-string build-list - (rename-out [alt-reverse reverse]) + reverse compose compose1) From 9d909d683416a904014763872f344d3b05a39e38 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 19 Oct 2015 16:03:25 -0400 Subject: [PATCH 376/381] Another validation check. Fixes bug caught by fuzz testing. --- racket/src/racket/src/validate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/racket/src/racket/src/validate.c b/racket/src/racket/src/validate.c index 90e2806796..e6b7640c89 100644 --- a/racket/src/racket/src/validate.c +++ b/racket/src/racket/src/validate.c @@ -1147,6 +1147,9 @@ static void module_validate(Scheme_Object *data, Mz_CPort *port, if (m->phaseless && m->prefix->num_stxes) scheme_ill_formed_code(port); + if (m->max_let_depth < 0) + scheme_ill_formed_code(port); + validate_toplevel(m->dummy, port, stack, tls, depth, delta, num_toplevels, num_stxes, num_lifts, tl_use_map, tl_state, tl_timestamp, From 1d3fe10d3dd6b688ccf39c18e7f330c172799faf Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 28 Oct 2015 11:31:32 -0400 Subject: [PATCH 377/381] Ensure that the closure_map is big enough when deserializing. Also document more invariants about the closure representation, and avoid some code duplication. Fixes #1108 (caught by fuzz testing). --- racket/src/racket/src/marshal.c | 7 ++++++- racket/src/racket/src/resolve.c | 2 +- racket/src/racket/src/schpriv.h | 12 +++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 44e7b7573d..a7ae4cddcb 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -792,7 +792,7 @@ static Scheme_Object *write_compiled_closure(Scheme_Object *obj) svec_size = data->closure_size; if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) { - svec_size += ((CLOS_TYPE_BITS_PER_ARG * (data->num_params + data->closure_size)) + BITS_PER_MZSHORT - 1) / BITS_PER_MZSHORT; + svec_size += boxmap_size(data->num_params + data->closure_size); { int k, mv; for (k = data->num_params + data->closure_size; --k; ) { @@ -1014,6 +1014,11 @@ static Scheme_Object *read_compiled_closure(Scheme_Object *obj) if (!(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS)) data->closure_size = SCHEME_SVEC_LEN(v); + + if ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS)) + if (data->closure_size + boxmap_size(data->closure_size + data->num_params) != SCHEME_SVEC_LEN(v)) + return NULL; + data->closure_map = SCHEME_SVEC_VEC(v); /* If the closure is empty, create the closure now */ diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index 45b6031e3a..f1bd0fea3b 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -1683,7 +1683,7 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info) /* closures */ /*========================================================================*/ -XFORM_NONGCING static int boxmap_size(int n) +XFORM_NONGCING int boxmap_size(int n) { return ((CLOS_TYPE_BITS_PER_ARG * n) + (BITS_PER_MZSHORT - 1)) / BITS_PER_MZSHORT; } diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index a4a2fcd96f..8da3285bec 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -2709,9 +2709,14 @@ typedef struct Scheme_Closure_Data Scheme_Inclhash_Object iso; /* keyex used for flags */ mzshort num_params; /* includes collecting arg if has_rest */ mzshort max_let_depth; - mzshort closure_size; - mzshort *closure_map; /* actually a Closure_Info* until resolved; if CLOS_HAS_TYPED_ARGS, - followed by bit array with CLOS_TYPE_BITS_PER_ARG bits per args then per closed-over */ + mzshort closure_size; /* the number of closed-over variables */ + mzshort *closure_map; /* actually a Closure_Info* until resolved; + contains closure_size elements mapping closed-over var to stack positions. + + If CLOS_HAS_TYPED_ARGS, that array is followed by bit array with + CLOS_TYPE_BITS_PER_ARG bits per args then per closed-over + + total size = closure_size + (closure_size + num_params) * CLOS_TYPE_BITS_PER_ARG */ Scheme_Object *code; Scheme_Object *name; /* name or (vector name src line col pos span generated?) */ void *tl_map; /* fixnum or bit array (as array of `int's) indicating which globals+lifts in prefix are used */ @@ -2732,6 +2737,7 @@ typedef struct Scheme_Closure_Data XFORM_NONGCING void scheme_boxmap_set(mzshort *boxmap, int j, int bit, int delta); XFORM_NONGCING int scheme_boxmap_get(mzshort *boxmap, int j, int delta); +XFORM_NONGCING int boxmap_size(int n); int scheme_has_method_property(Scheme_Object *code); From ef6a5c2e75f79a7328e32f4050d73fa5681355ea Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 27 Oct 2015 17:11:37 -0400 Subject: [PATCH 378/381] Add test case for match ordering bug. --- pkgs/racket-test/tests/match/examples.rkt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/racket-test/tests/match/examples.rkt b/pkgs/racket-test/tests/match/examples.rkt index e9a0c97921..22cbee956e 100644 --- a/pkgs/racket-test/tests/match/examples.rkt +++ b/pkgs/racket-test/tests/match/examples.rkt @@ -801,5 +801,13 @@ (check-equal? (match 42 [(foo) x]) 42)) + + (test-case "ordering" + (define b (box #t)) + (check-equal? + (match b + [(and x (? (λ _ (set-box! b #f))) (app unbox #f)) 'yes] + [_ 'no]) + 'yes)) )) From 60fb3e06b252532dd492372c3736fa58f8562508 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 26 Oct 2015 09:12:27 -0400 Subject: [PATCH 379/381] Improve set! error messages. --- racket/src/racket/src/compenv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/src/compenv.c b/racket/src/racket/src/compenv.c index 1c239e965a..34eaaae6d9 100644 --- a/racket/src/racket/src/compenv.c +++ b/racket/src/racket/src/compenv.c @@ -1408,7 +1408,8 @@ scheme_compile_lookup(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, scheme_unbound_syntax(((flags & SCHEME_SETTING) ? scheme_set_stx_string : scheme_var_ref_string), - NULL, src_find_id, "unbound identifier in module"); + NULL, src_find_id, "unbound identifier in module", + scheme_stx_describe_context(src_find_id, scheme_env_phase(genv), 0)); return NULL; } if (flags & SCHEME_NULL_FOR_UNBOUND) @@ -1494,7 +1495,8 @@ scheme_compile_lookup(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, scheme_unbound_syntax(((flags & SCHEME_SETTING) ? scheme_set_stx_string : scheme_var_ref_string), - NULL, src_find_id, "unbound identifier in module"); + NULL, src_find_id, "unbound identifier in module", + scheme_stx_describe_context(src_find_id, scheme_env_phase(genv), 0)); return NULL; } } From 685e74a1c64db63b5cdfa809509194d3b16a0102 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 29 Oct 2015 15:52:51 -0400 Subject: [PATCH 380/381] fix debugging mode for checking runstack overflow --- racket/src/racket/src/jit.h | 8 +++++--- racket/src/racket/src/jitcall.c | 2 +- racket/src/racket/src/jitstack.c | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index c72762ed7d..694c8823aa 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -716,15 +716,16 @@ static void *top4; #define mz_popr_p(x) scheme_mz_popr_p_it(jitter, x, 0) #define mz_popr_x() scheme_mz_popr_p_it(jitter, JIT_R1, 1) -#if 0 +#define CHECK_RUNSTACK_REGISTER_UPDATE 0 + +#if CHECK_RUNSTACK_REGISTER_UPDATE /* Debugging: at each _finish(), double-check that the runstack register has been copied into scheme_current_runstack. This code assumes that mz_finishr() is not used with JIT_R0. Failure is "reported" by going into an immediate loop, but check_location is set to the source line number to help indicate where the problem originated. */ static void *top; -int check_location; -# define CONFIRM_RUNSTACK() (jit_movi_l(JIT_R0, __LINE__), jit_sti_l(&check_location, JIT_R0), \ +# define CONFIRM_RUNSTACK() (jit_movi_l(JIT_R0, __LINE__), \ mz_tl_ldi_p(JIT_R0, tl_MZ_RUNSTACK), top = (_jit.x.pc), jit_bner_p(top, JIT_RUNSTACK, JIT_R0)) #else # define CONFIRM_RUNSTACK() 0 @@ -733,6 +734,7 @@ int check_location; #define mz_prepare(x) jit_prepare(x) #define mz_finish(x) ((void)CONFIRM_RUNSTACK(), jit_finish(x)) #define mz_finishr(x) ((void)CONFIRM_RUNSTACK(), jit_finishr(x)) +#define mz_finish_unsynced_runstack(x) jit_finish(x) #define mz_nonrs_finish(x) jit_finish(x) diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index eaba449d5d..6276c1f76d 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -93,7 +93,7 @@ static jit_insn *generate_proc_struct_retry(mz_jit_state *jitter, int num_rands, jit_movi_i(JIT_R0, num_rands); jit_pusharg_i(JIT_R0); /* argc */ jit_pusharg_p(JIT_R1); /* closure */ - (void)mz_finish(scheme_native_arity_check); + (void)mz_finish_unsynced_runstack(scheme_native_arity_check); CHECK_LIMIT(); jit_retval(JIT_R0); refz5 = jit_beqi_i(jit_forward(), JIT_R0, 0); diff --git a/racket/src/racket/src/jitstack.c b/racket/src/racket/src/jitstack.c index 52fe69a40f..b13b2577d3 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -694,7 +694,7 @@ typedef void (*Thread_Start_Child_Proc)(Scheme_Thread *child, Scheme_Object *chi void *scheme_module_run_start(Scheme_Env *menv, Scheme_Env *env, Scheme_Object *name) { Module_Run_Proc proc = (Module_Run_Proc)sjc.module_run_start_code; - if (proc) + if (proc && !CHECK_RUNSTACK_REGISTER_UPDATE) return proc(menv, env, &name); else return scheme_module_run_finish(menv, env); @@ -703,7 +703,7 @@ void *scheme_module_run_start(Scheme_Env *menv, Scheme_Env *env, Scheme_Object * void *scheme_module_exprun_start(Scheme_Env *menv, int set_ns, Scheme_Object *name) { Module_Exprun_Proc proc = (Module_Exprun_Proc)sjc.module_exprun_start_code; - if (proc) + if (proc && !CHECK_RUNSTACK_REGISTER_UPDATE) return proc(menv, set_ns, &name); else return scheme_module_exprun_finish(menv, set_ns); @@ -712,7 +712,7 @@ void *scheme_module_exprun_start(Scheme_Env *menv, int set_ns, Scheme_Object *na void *scheme_module_start_start(struct Start_Module_Args *a, Scheme_Object *name) { Module_Start_Proc proc = (Module_Start_Proc)sjc.module_start_start_code; - if (proc) + if (proc && !CHECK_RUNSTACK_REGISTER_UPDATE) return proc(a, &name); else return scheme_module_start_finish(a); @@ -722,7 +722,7 @@ void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk) XFORM_SKIP_PROC { Thread_Start_Child_Proc proc = (Thread_Start_Child_Proc)sjc.thread_start_child_code; - if (proc) + if (proc && !CHECK_RUNSTACK_REGISTER_UPDATE) proc(child, child_thunk); else scheme_do_thread_start_child(child, child_thunk); From 6e21376473f8bd3520b9bc611982bf2149f5fd5c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 29 Oct 2015 16:14:14 -0400 Subject: [PATCH 381/381] fix relative-path handling for source locations in bytecode Closes PR 15174 --- pkgs/racket-test-core/tests/racket/stx.rktl | 23 +++++++++++++++++++++ racket/src/racket/src/file.c | 2 +- racket/src/racket/src/marshal.c | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/stx.rktl b/pkgs/racket-test-core/tests/racket/stx.rktl index 5cce96d9e6..838992b882 100644 --- a/pkgs/racket-test-core/tests/racket/stx.rktl +++ b/pkgs/racket-test-core/tests/racket/stx.rktl @@ -2204,6 +2204,29 @@ name)]))) (eval '(m racket/base values))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check marshaling and unmarshaling with relative paths + +(let () + (define dir (find-system-path 'temp-dir)) + + (define x (parameterize ([current-namespace (make-base-namespace)]) + (compile (datum->syntax #f '#'x (vector (build-path dir "sub" "x.rkt") + 1 + 1 + 1 + 1))))) + (define-values (i o) (make-pipe)) + (parameterize ([current-write-relative-directory + (cons (build-path dir "nested") + dir)]) + (write x o)) + (test (build-path dir "inner" 'up "sub" "x.rkt") + syntax-source + (eval (parameterize ([read-accept-compiled #t] + [current-load-relative-directory (build-path dir "inner")]) + (read i))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index b892d78529..1d0c40f16d 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -5693,7 +5693,7 @@ Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir while (!SCHEME_NULLP(be)) { if (cache) { - obj = scheme_make_pair(up_symbol, scheme_null); + obj = scheme_make_pair(up_symbol, obj); } else { a[0] = up_symbol; a[1] = obj; diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index a7ae4cddcb..b64b84866d 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -747,7 +747,7 @@ static Scheme_Object *read_quote_syntax(Scheme_Object *obj) static int not_relative_path(Scheme_Object *p, Scheme_Hash_Table *cache) { Scheme_Object *dir, *rel_p; - + dir = scheme_get_param(scheme_current_config(), MZCONFIG_WRITE_DIRECTORY); if (SCHEME_TRUEP(dir)) {